Prose
Stored rich text, displayed — approval notes, comments, return instructions rendered on record detail, in cards, or in print. One class styles the native elements; pairs with the rich text editor chrome but needs none of it.
Rendered content
Return authorization RMA-2210
Customer reports intermittent fault after firmware 2.4; unit powers off under load.
- Serial verified against the delivery
- Warranty valid until 2027-03-01
| Item | Qty | Disposition |
|---|---|---|
| Controller unit | 1 | Replace |
| Power cable | 1 | Keep |
Customer prefers replacement over repair — confirmed by phone 2026-08-12.
View code
<div class="bo-prose">
<h2>Return authorization RMA-2210</h2>
<p>Customer reports <strong>intermittent fault</strong> after firmware
2.4; unit powers off under load.</p>
<ul>
<li>Serial verified against the delivery</li>
<li>Warranty valid until 2027-03-01</li>
</ul>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Disposition</th></tr></thead>
<tbody>
<tr><td>Controller unit</td><td>1</td><td>Replace</td></tr>
<tr><td>Power cable</td><td>1</td><td>Keep</td></tr>
</tbody>
</table>
<blockquote>Customer prefers replacement over repair — confirmed by
phone 2026-08-12.</blockquote>
</div> Headings, lists, blockquotes, inline code, and a bordered lite table — stored content just needs to read well; real data screens use the data table. First and last children drop their outer margins, so prose sits flush inside padded containers.
Inside a card
View code
<article class="bo-widget">
<header class="bo-widget__header">
<span class="bo-badge bo-badge--type">Approval note</span>
<span class="bo-byline"><strong>J. Kim</strong> · Cost-centre manager</span>
</header>
<div class="bo-widget__body bo-prose">
<p>Approved with <em>one exception</em> — line 3 ships from
<strong>Hamburg</strong> instead:</p>
<ol><li>Confirm HAM-02 stock</li><li>Update the delivery date</li></ol>
</div>
</article> Compose freely — a widget body, a timeline entry, a dialog. The class carries no chrome of its own, so the container's padding and background stay in charge.
Markup
<!-- One class on the wrapper; the CONTENT is native elements
(headings, lists, blockquote, code, tables) exactly as stored.
No per-element opt-in, no markup transformation. -->
<div class="bo-prose">
<h2>…</h2>
<p>… <strong>…</strong> …</p>
<table>…</table>
</div> Quick reference generated
| Class | Role |
|---|---|
| .bo-prose | block (root) |
API generated from CSS
| Blocks | bo-prose |
|---|---|
| JS required | None — CSS-only. |
- Sanitize stored HTML on the server before it ever reaches this class — rendered rich text is untrusted input (the rich text page has the full guidance, including why a tag allowlist alone leaks script text).
- Stored content may contain
h1s or skipped levels: demote server-side so your page outline stays sane. - Prose tables print like data tables — headers repeat per page, rows never split (print/index.css).
- Displaying inside the editor chrome? Put the class on
.bo-richtext__content— same styles while editing and when rendered.
Contrast — 18 AA pairs this component uses (generated, CI-gated)
| Text | on | Light | Dark |
|---|---|---|---|
| text-primary | bg-surface | 17.74 | 16.15 |
| text-primary | bg-canvas | 16.98 | 18.08 |
| text-secondary | bg-surface | 10.31 | 11.46 |
| text-secondary | bg-muted | 9.37 | 9.75 |
| text-muted | bg-muted | 6.87 | 5.66 |
| bg-surface | text-primary | 17.74 | 16.15 |
| text-primary | bg-hover | 16.12 | 13.75 |
| text-primary | bg-selected | 17.01 | 11.86 |
| text-secondary | bg-selected | 9.88 | 8.41 |
| text-primary | bg-surface-raised | 17.74 | 14.51 |
| text-secondary | bg-canvas | 9.86 | 12.82 |
| border-control | bg-muted | 4.39 | 5.66 |
| accent | bg-muted | 4.97 | 7.72 |
| warning-strong | bg-muted | 4.56 | 6.69 |
| danger | bg-muted | 4.39 | 5.19 |
| text-primary | bg-muted | 16.12 | 13.75 |
| success-text | bg-muted | 4.56 | 10.23 |
| danger-text | bg-muted | 5.88 | 7.57 |
Maturity generated
- Introduced
- v0.3.0
- CSS floor
- Chrome/Edge 99 · Firefox 97 · Safari 15.4
- Alignment scored
- 2026-08-21
- Assistive-tech evidence
- None recorded
Pin this component's first release with npm i @busy-office/ui@0.3.0.
The floor is derived from this component's stylesheet alone — set by
@layer — so it sits at or below the
whole framework's Chrome/Edge 119 · Firefox 129 · Safari 17.5.
No assistive-technology runtime result is recorded for any component: it needs a human listening to VoiceOver and NVDA on owner hardware; no gate in this repo can simulate announcement behaviour.
What automation covers instead is test:axe across every page at 1440 and 390, and check:forced-colors — see
accessibility.
Design-system alignment generated
100% (15/15) — how closely this component follows the design language. Each rule is scored 0-3 against a checkable citation; rules that don't apply leave the denominator. Scored 2026-08-21.
| Rule | Score | Evidence |
|---|---|---|
| Typography | 3 / 3 | inline code consumes --bo-font-size-mono-inline; every heading level still comes from the scale (94.13) |
| Colour | 3 / 3 | zero raw colour |
| Spacing | 3 / 3 | the 3px quote rule and the em code padding both carry their reason, incl. why the padding must stay thin vertically (94.6b) |
| Interaction | n/a | display-only; the editor chrome is .bo-richtext |
| Content | 3 / 3 | renders whatever stored rich text a server sends, so the choice is upstream of this class; EXEMPT in check:wrong-choice |
| Fit | 3 / 3 | stored rich text wherever it is DISPLAYED — record detail, comments, print; split from richtext so display-only consumers skip the editor |