Kanzo UI
Data display

Prose

Styles a block of rendered long-form content — markdown, a changelog, an article.

Posting a contract

Every contract on the board carries a grade and a region. Tags are optional but strongly encouraged — they are what lets a warden find the work she is equipped for rather than reading the board end to end.

A contract nobody tagged is a contract the right party never sees.

Required fields

  • Title — what a scout would call it, not a case number.
  • Due — a date the party can walk to and back from.
  • Posting hall — a charter, not a person's name.

Usage

import { Prose } from "@kanzo-tech/ui";
<Prose dangerouslySetInnerHTML={{ __html: renderedMarkdown }} />

Reach for it when you are styling a tree of elements you did not author — the output of a markdown renderer, a CMS, a changelog. Nothing inside needs a class.

The only typography component

There is no Heading and no Text, and that is the rule rather than an omission. A Text taking size, weight, variant, align and truncate is five styling knobs on a <span> — styling-by-props competing with the utilities, which is the ad-hoc styling the conventions exist to prevent. Every component styles its own text instead, which is what Shark does and what the type scale is for. Reach for a new component last: this one is rung 1, and rung 1 is a class.

So: chrome styles itself, Prose handles what utilities cannot. For a heading in your own interface, write the element and the utilities — <h2 className="text-lg font-semibold"> — or use the component that owns that region, such as SectionTitle.

The class is kanzo-prose

Prose is a class name with a component around it, so the name matters: the plugin is registered as kanzo-prose, not prose. It emits unscoped descendant rules — .prose :where(a), :where(h1), :where(table) — whose specificity beats Preflight, so under the default name every consumer who happens to use prose themselves (fumadocs does; it is a common choice) would have their anchors, headings, lists and tables repainted by a library they asked for a Button. Target kanzo-prose when you style it, and pass className when you want a different measure.

Theming

Prose is the one component whose element rules we do not own — they come from Tailwind's typography plugin, because rendered markdown has dozens of them and hand-writing them is how a design system ends up maintaining a worse copy of a solved problem.

Its palette is ours, though: the plugin's own variables are re-pointed at the Kanzo tokens in styles.css, so Prose re-skins with everything else. The dark variants point at the same tokens rather than a second palette — the tokens already flip with .dark, and a separate dark set would be a second source of truth.

Width

max-w-[65ch] and centred by default, which is the readable measure for body text. Override with className when the container already constrains the line length.

API Reference

No props of its own, and no variants — the element rules come from the kanzo-prose class.

Extends React.ComponentProps<typeof ark.div>, so children, dangerouslySetInnerHTML, className, ref and every native div prop pass through. The only styling it applies is kanzo-prose mx-auto max-w-[65ch], all three overridable from className.

On this page