Adoption reference · v3.5.0

Components, with the contract attached.

Copy the markup, then read the anatomy and accessibility notes before adapting it. This page is generated from component-manifest.json, so agents, maintainers, and humans share one inventory.

01 · Since 1.0.0

Type styles

#type-styles

.t-display .t-h1 .t-h2 .t-h3 .t-lede .t-body .t-small .t-caption

Anatomy

  • Apply one type class to a semantic heading or text element.
  • Keep the HTML heading level independent from the visual class.

Modifiers

  • .t-display through .t-caption select scale and voice.

States

  • Responsive display sizing is token-driven.

Accessibility

  • Preserve a logical heading outline; visual size does not determine heading rank.

JavaScript contract

None.

<h2 class="t-h1">A semantic heading</h2>
<p class="t-lede">A concise editorial introduction.</p>
02 · Since 1.4.0

Editorial primitives

#editorial

.dropcap .pullquote .byline .figure .eyebrow-serif

Anatomy

  • Use inside prose with a 60–65ch measure.
  • Figure captions belong inside figure.

Modifiers

  • .eyebrow-serif is the editorial counterpart to product-oriented .eyebrow.

States

  • Figures and pull quotes avoid breaks in print.

Accessibility

  • Use blockquote for quotations and meaningful alt text for figure images.

JavaScript contract

None.

<blockquote class="pullquote">Quiet interfaces leave room for the work.</blockquote>
03 · Since 1.0.0

Button

#button

.btn .btn-primary .btn-secondary .btn-ghost .btn-danger .btn-sm

Anatomy

  • .btn supplies structure; add one intent modifier.
  • Use a native button for actions and an anchor for navigation.

Modifiers

  • Primary, secondary, ghost, danger, and small.

States

  • Hover, active, disabled, .is-disabled, and aria-busy=true.

Accessibility

  • Pair aria-busy=true with disabled while an action is pending.
  • Icon-only buttons need an accessible name.

JavaScript contract

Only the product action; Inkwell supplies state styling.

<button class="btn btn-primary" type="button">Save changes</button>
04 · Since 1.0.0

Text controls

#form-controls

.input .textarea .select

Anatomy

  • Place a labelled control inside .field.
  • Use .textarea for multi-line input and .select on native select.

Modifiers

  • .is-error and .is-disabled.

States

  • Focus, disabled, placeholder, and invalid.

Accessibility

  • Every control needs a label and name.
  • Invalid controls set aria-invalid=true and reference error copy with aria-describedby.

JavaScript contract

Application validation only.

<label class="field" for="reference-email">
  <span class="field-label">Email</span>
  <input class="input" id="reference-email" name="email" type="email" autocomplete="email">
</label>
05 · Since 1.3.0

Field group

#field

.field .field-label .field-help .field-error .field-row

Anatomy

  • Label, control, then helper or error text.
  • .field-row aligns related controls without removing labels.

Modifiers

  • Helper and error copy are mutually contextual, not visual replacements for labels.

States

  • Normal, help, and invalid.

Accessibility

  • Connect help or error IDs from the control with aria-describedby.

JavaScript contract

Application validation only.

<div class="field">
  <label class="field-label" for="reference-slug">Slug</label>
  <input class="input is-error" id="reference-slug" name="slug" aria-invalid="true" aria-describedby="reference-slug-error">
  <span class="field-error" id="reference-slug-error">Use letters, numbers, and hyphens.</span>
</div>
06 · Since 1.0.0

Choice controls

#choice-controls

.checkbox .radio .switch

Anatomy

  • Wrap a native input and visible text in the matching label class.

Modifiers

  • Checkbox for independent choices, radio for one-of-many, switch for immediate settings.

States

  • Checked, unchecked, focus-visible, and disabled native states.

Accessibility

  • Radio groups need a fieldset and legend.
  • Do not use a switch for a submit-time preference.

JavaScript contract

None for native state; application behavior may respond to change.

<label class="checkbox"><input type="checkbox" name="updates"> Product updates</label>
07 · Since 1.4.0

Segmented control

#segmented

.segmented .seg

Anatomy

  • A .segmented group containing two to four buttons or .seg items.

Modifiers

  • Mark the selected option with aria-pressed=true or .is-active.

States

  • Selected, hover, and focus-visible.

Accessibility

  • Give the group an accessible label and expose selection with aria-pressed.

JavaScript contract

Application code updates the selected choice.

<div class="segmented" role="group" aria-label="Density">
  <button class="seg" type="button" aria-pressed="true">Comfortable</button>
  <button class="seg" type="button" aria-pressed="false">Compact</button>
</div>
08 · Since 1.0.0

Badge

#badge

.badge .badge-neutral .badge-accent .badge-success .badge-warning .badge-danger

Anatomy

  • Short, non-interactive status text inside .badge.

Modifiers

  • Neutral, accent, success, warning, and danger.

States

  • Static status only.

Accessibility

  • Do not rely on hue alone; the label must name the status.

JavaScript contract

None.

<span class="badge badge-success">Published</span>
09 · Since 1.0.0

Issue pill

#pill

.pill .sev .resolved

Anatomy

  • Compact severity or resolution label.

Modifiers

  • .sev for severity and .resolved for completed findings.

States

  • Static status only.

Accessibility

  • Include meaningful status text; color is supplemental.

JavaScript contract

None.

<span class="pill resolved">Resolved</span>
10 · Since 1.0.0

Card

#card

.card .card.is-link

Anatomy

  • Paper surface containing an optional title and body.

Modifiers

  • .is-link adds a restrained hover affordance to a genuinely linked card.

States

  • Base and linked hover.

Accessibility

  • If the whole card navigates, use one clear anchor rather than nested interactive elements.

JavaScript contract

None.

<article class="card"><h3 class="t-h3">Release notes</h3><p class="t-small">What changed and why.</p></article>
11 · Since 2.1.0

Card grid

#card-grid

.card-grid

Anatomy

  • Responsive parent for sibling cards.

Modifiers

  • Override the minimum column size only when content requires it.

States

  • Auto-fills from one column upward.

Accessibility

  • DOM order remains reading order; do not rearrange items visually.

JavaScript contract

None.

<div class="card-grid"><article class="card">First</article><article class="card">Second</article></div>
12 · Since 1.0.0

Stat card

#stat-card

.stat-card .stat-label .stat-num .stat-delta

Anatomy

  • Label, prominent value, and optional directional delta.

Modifiers

  • .is-primary changes the full border to accent; .up and .down color deltas.

States

  • Default and primary emphasis.

Accessibility

  • Write the direction in text or accessible copy; arrows and color are supplemental.

JavaScript contract

None.

<article class="stat-card is-primary"><div class="stat-label">Adoption</div><div class="stat-num">68%</div><div class="stat-delta up">Up 12%</div></article>
13 · Since 1.0.0

Avatar

#avatar

.avatar

Anatomy

  • Image or initials inside .avatar; groups overlap siblings.

Modifiers

  • No public size modifiers; override dimensions locally only when the surrounding pattern requires it.

States

  • Static identity display.

Accessibility

  • Use meaningful alt text when the identity is not repeated nearby; otherwise use empty alt.

JavaScript contract

None.

<span class="avatar" aria-label="Ada Lovelace">AL</span>
14 · Since 1.0.0

Status chip

#chip-dot

.chip-dot .dot .safe .medium .attention

Anatomy

  • A visible dot plus a textual status label.

Modifiers

  • Safe, medium, and attention.

States

  • Static status only.

Accessibility

  • Keep the text label; the dot is intentionally not the sole signal.

JavaScript contract

None.

<span class="chip-dot safe"><span class="dot" aria-hidden="true"></span>Healthy</span>
15 · Since 1.0.0

Timeline

#timeline

.timeline .tl-entry

Anatomy

  • Ordered entries containing date, title, and optional description.

Modifiers

  • No public visual modifiers.

States

  • Chronological static content.

Accessibility

  • Use an ordered list when sequence matters and machine-readable time elements for dates.

JavaScript contract

None.

<ol class="timeline"><li class="tl-entry"><time class="t-caption" datetime="2026-08-27">Aug 27</time><h3 class="t-h3">Release</h3></li></ol>
16 · Since 1.0.0

TL;DR panel

#tldr

.tldr .tldr-label

Anatomy

  • Dark summary panel with a label and concise content.

Modifiers

  • No public modifiers.

States

  • Print swaps the fill for an ink border.

Accessibility

  • Do not hide essential details exclusively in the summary.

JavaScript contract

None.

<aside class="tldr"><div class="tldr-label">TL;DR</div><p>Three files install the complete CSS system.</p></aside>
17 · Since 1.0.0

Section heading

#section-heading

.sec-head .idx .count

Anatomy

  • Optional index, semantic h1 or h2, and optional count.

Modifiers

  • Use the index only when sequence carries meaning.

States

  • Responsive wrapping follows content.

Accessibility

  • Use the correct semantic heading rank; the class styles h1 and h2 equally.

JavaScript contract

None.

<div class="sec-head"><span class="idx">02</span><h2>Components</h2><span class="count">34 families</span></div>
18 · Since 1.0.0

Breadcrumbs

#breadcrumbs

.breadcrumbs

Anatomy

  • A labelled nav containing an ordered list of ancestors and current page.

Modifiers

  • No public modifiers.

States

  • Current page uses aria-current=page.

Accessibility

  • Set aria-label=Breadcrumb on nav and aria-current=page on the last item.

JavaScript contract

None.

<nav class="breadcrumbs" aria-label="Breadcrumb"><ol><li><a href="/">Home</a></li><li aria-current="page">Components</li></ol></nav>
19 · Since 1.0.0

Tabs

#tabs

.tabs .tab [data-tabs]

Anatomy

  • A labelled tablist of tabs plus one labelled panel per tab.
  • Each tab's aria-controls points to its panel; each panel's aria-labelledby points back.

Modifiers

  • aria-selected=true marks the active tab.

States

  • Selected, hover, focus-visible, and hidden panels.

Accessibility

  • Use roving tabindex and ArrowLeft/ArrowRight/Home/End navigation.
  • Do not use tabs when users need to compare panels simultaneously.

JavaScript contract

Load inkwell-interactions.js or reproduce the documented WAI-ARIA behavior.

<div class="tabs" role="tablist" aria-label="Account views" data-tabs>
  <button class="tab" id="ref-tab-overview" role="tab" aria-selected="true" aria-controls="ref-panel-overview">Overview</button>
  <button class="tab" id="ref-tab-activity" role="tab" aria-selected="false" aria-controls="ref-panel-activity" tabindex="-1">Activity</button>
</div>
<div id="ref-panel-overview" role="tabpanel" aria-labelledby="ref-tab-overview">Overview content</div>
<div id="ref-panel-activity" role="tabpanel" aria-labelledby="ref-tab-activity" hidden>Activity content</div>
20 · Since 1.0.0

Alert

#alert

.alert .alert-title .alert-body

Anatomy

  • Optional title followed by concise guidance.

Modifiers

  • .is-info, .is-success, .is-warning, and .is-danger.

States

  • Persistent notice or dynamically announced alert.

Accessibility

  • Use role=alert only for important content inserted after load; static notices need no live role.

JavaScript contract

None unless the product inserts or dismisses the alert.

<div class="alert is-info"><div class="alert-title">Before you continue</div><p class="alert-body">Review the generated changes.</p></div>
21 · Since 3.1.0

Callout

#callout

.callout .callout-label .callout-body

Anatomy

  • Label and emphasized editorial statement inside a ruled panel.

Modifiers

  • .is-accent for brand emphasis.

States

  • Static emphasis.

Accessibility

  • Use an aside when the callout is complementary; do not use visual treatment as heading semantics.

JavaScript contract

None.

<aside class="callout is-accent"><div class="callout-label">Adoption note</div><p class="callout-body">Start with the canonical entry file.</p></aside>
22 · Since 3.1.0

Cited findings

#findings

.findings .finding .finding-num .finding-text .finding-src

Anatomy

  • A list of numbered findings, each with statement and source.

Modifiers

  • No public modifiers.

States

  • Stacks on narrow screens.

Accessibility

  • Use an ordered list when numbering communicates order; source links need descriptive labels.

JavaScript contract

None.

<ol class="findings"><li class="finding"><span class="finding-num">01</span><p class="finding-text">Reference pages reduce adoption uncertainty. <cite class="finding-src">Repository review</cite></p></li></ol>
23 · Since 1.0.0

Code block

#code-block

.code-block

Anatomy

  • Optional label and pre/code pair inside a framed block.

Modifiers

  • No public modifiers.

States

  • Scrolls internally when code is wider than its container.

Accessibility

  • Keep commands as selectable text and identify the language in nearby copy when relevant.

JavaScript contract

None; copy buttons are an application enhancement.

<div class="code-block"><pre><code>&lt;link rel="stylesheet" href="inkwell.css"&gt;</code></pre></div>
24 · Since 1.3.0

Dialog

#dialog

.dialog .dialog-head .dialog-body .dialog-foot .dialog-close [data-dialog-open] [data-dialog-close]

Anatomy

  • Native dialog with head, labelled title, body, and action footer.
  • A trigger's data-dialog-open value matches the dialog ID.

Modifiers

  • No public visual modifiers.

States

  • Closed, modal open, cancel, and return-focus.

Accessibility

  • Use native dialog.showModal(), aria-labelledby, an obvious close action, and restore focus to the trigger.

JavaScript contract

inkwell-interactions.js wires data-dialog-open and data-dialog-close; native Escape handles cancel.

<button class="btn btn-secondary" type="button" data-dialog-open="reference-dialog">Open dialog</button>
<dialog class="dialog" id="reference-dialog" aria-labelledby="reference-dialog-title">
  <div class="dialog-head"><h2 id="reference-dialog-title">Confirm</h2><button class="dialog-close" type="button" aria-label="Close" data-dialog-close>×</button></div>
  <div class="dialog-body">Continue with this change?</div>
  <div class="dialog-foot"><button class="btn btn-secondary" type="button" data-dialog-close>Cancel</button></div>
</dialog>
25 · Since 1.0.0

Skeleton

#skeleton

.skeleton .skeleton.is-text .skeleton.is-title .skeleton.is-block .skeleton.is-circle

Anatomy

  • Decorative blocks that approximate pending content.

Modifiers

  • Line and circle shapes.

States

  • Animated normally, static under reduced motion and print.

Accessibility

  • Hide decorative skeletons from assistive tech and mark the containing region aria-busy=true.

JavaScript contract

Application code removes the skeleton and clears aria-busy when content arrives.

<div aria-busy="true" aria-label="Loading profile"><div class="skeleton is-text" aria-hidden="true"></div></div>
26 · Since 1.0.0

Table

#table

.tbl .tbl-scroll

Anatomy

  • Semantic table wrapped in .tbl-scroll when columns may exceed the viewport.

Modifiers

  • No public modifiers.

States

  • Container-level horizontal scroll on narrow screens.

Accessibility

  • Provide a caption, use th with scope, and keep page-level scrolling vertical.

JavaScript contract

None.

<div class="tbl-scroll"><table class="tbl"><caption class="sr-only">Release status</caption><thead><tr><th scope="col">Version</th><th scope="col">Status</th></tr></thead><tbody><tr><td>3.5.0</td><td>Ready</td></tr></tbody></table></div>
27 · Since 1.0.0

Table of contents

#toc

.toc

Anatomy

  • Labelled navigation list of in-page section links.

Modifiers

  • Optional .n number within each link.

States

  • Hover and focus-visible.

Accessibility

  • Wrap in nav with an accessible label; target IDs must exist.

JavaScript contract

None.

<nav class="toc" aria-label="On this page"><a href="#reference-install"><span class="n">01</span> Install</a></nav>
28 · Since 1.0.0

Pagination

#pagination

.pagination

Anatomy

  • Labelled navigation containing page links.

Modifiers

  • aria-current=page marks the current page.

States

  • Current, hover, focus-visible, and disabled button states.

Accessibility

  • Give nav a label and each ambiguous numeric link a useful accessible name.

JavaScript contract

None for links; client-side routers may intercept navigation.

<nav class="pagination" aria-label="Pagination"><a href="?page=1" aria-current="page" aria-label="Page 1">1</a><a href="?page=2" aria-label="Page 2">2</a></nav>
29 · Since 1.0.0

Empty state

#empty-state

.empty-state .empty-state-icon

Anatomy

  • Optional decorative icon, heading, explanation, and one next action.

Modifiers

  • No public modifiers.

States

  • Empty content only.

Accessibility

  • Use a semantic heading and hide decorative icon glyphs with aria-hidden=true.

JavaScript contract

None.

<section class="empty-state"><div class="empty-state-icon" aria-hidden="true">◎</div><h2>Nothing here yet</h2><p>Create the first item to get started.</p><button class="btn btn-primary" type="button">Create item</button></section>
30 · Since 3.5.0

Disclosure

#disclosure

.disclosure

Anatomy

  • Native details.disclosure containing summary followed by content.

Modifiers

  • The native open attribute controls expanded state.

States

  • Collapsed, expanded, hover, and focus-visible.

Accessibility

  • Keep summary concise and unique; native details exposes expanded state and keyboard behavior.

JavaScript contract

None.

<details class="disclosure"><summary>Does this need JavaScript?</summary><p>No. The native details element owns the behavior.</p></details>
31 · Since 3.2.0

Editorial carousel

#carousel

.carousel .carousel-track .carousel-slide .carousel-controls .carousel-btn .carousel-dot [data-carousel]

Anatomy

  • Named carousel region, focusable snap track, labelled slides, and initially hidden controls.

Modifiers

  • No autoplay or visual variants.

States

  • Current slide, first/last disabled controls, swipe, keyboard, and reduced motion.

Accessibility

  • Name the region and each slide, keep the track keyboard-scrollable, and never autoplay.

JavaScript contract

inkwell-interactions.js reveals controls, creates labelled dots, and handles arrows/Home/End. Swipe and scroll work without it.

<section class="carousel" data-carousel aria-roledescription="carousel" aria-label="Release tour">
  <div class="carousel-track" tabindex="0">
    <article class="carousel-slide" role="group" aria-roledescription="slide" aria-label="1 of 2">First slide</article>
    <article class="carousel-slide" role="group" aria-roledescription="slide" aria-label="2 of 2">Second slide</article>
  </div>
  <div class="carousel-controls" hidden><button class="carousel-btn" type="button" data-carousel-prev aria-label="Previous slide">←</button><div class="carousel-dots"></div><button class="carousel-btn" type="button" data-carousel-next aria-label="Next slide">→</button></div>
</section>
32 · Since 2.1.0

Navbar

#navbar

.navbar .navbar-inner .brand

Anatomy

  • Sticky navbar, constrained inner row, brand link, and navigation.

Modifiers

  • Optional .dot inside the brand.

States

  • Sticky position and link hover/focus.

Accessibility

  • Label multiple nav landmarks and mark the current page with aria-current=page.

JavaScript contract

None.

<header class="navbar"><div class="navbar-inner"><a class="brand" href="/"><span class="dot" aria-hidden="true"></span>Inkwell</a><nav aria-label="Primary"><a href="/docs.html">Docs</a></nav></div></header>
33 · Since 1.0.0

Layout wraps

#layout-wraps

.wrap .wrap-narrow .wrap-wide

Anatomy

  • A max-width container with responsive horizontal page padding.

Modifiers

  • Narrow, default, and wide content measures.

States

  • Fluid until each maximum width.

Accessibility

  • Layout classes do not replace semantic landmarks.

JavaScript contract

None.

<main class="wrap"><h1 class="t-display">Page title</h1></main>
34 · Since 2.1.0

Accessibility utilities

#accessibility-utilities

.sr-only .skip-link

Anatomy

  • .sr-only preserves accessible text visually; .skip-link becomes visible on focus.

Modifiers

  • No public modifiers.

States

  • Skip link hidden until focus-visible.

Accessibility

  • Every page should place the skip link first in body and target its main landmark.

JavaScript contract

None.

<a class="skip-link" href="#main-content">Skip to content</a>
<main id="main-content">…</main>
35 · Since 1.3.0

Keyboard chip

#keyboard-chip

.kbd

Anatomy

  • Use the semantic kbd element for a single key or chord.

Modifiers

  • .kbd is available when semantic kbd is not applicable.

States

  • Static inline content.

Accessibility

  • Write the shortcut in surrounding text and use platform-appropriate key names.

JavaScript contract

None.

<p>Press <kbd>⌘</kbd> <kbd>K</kbd> to search.</p>