component

TuxProse

Typographic shell for long-form markdown content. Wraps <MDCRenderer> output, hand-authored HTML, or any slot that mixes headings, paragraphs, lists, tables, code, and blockquotes. Applies the four-family rule + the maroon-underlined H2 rhythm — same shape as .heading--bold but through the prose layer, so authors don't need to add utility classes inside markdown.

why

One source of truth

Before TuxProse, /design/[doc], /changelog, and /markdown each shipped a ~130-line scoped :deep() block to style their renderer output, with a "keep these in sync" comment that nobody loves. TuxProse consolidates those into one component. Pull a new long-form surface into existence (an ADR page, a docs route) and wrap the renderer in <TuxProse> — done.

markdown renderer

With MDCRenderer

The canonical use. Wrap the renderer in <TuxProse>; everything below picks up the rhythm automatically.

How the agent watcher works

Landscape's file watcher is the long-running process on each agent host that detects file events (create / modify / delete / move) and ships them to the central index.

Event types

The watcher emits four event types upstream:

TypeTriggers when…
createA new inode appears in a watched root
modifyAn existing inode's content or mtime changes
deleteAn inode disappears (soft-delete with 30d retention)
moveAn inode's path changes — single event, never delete+create
Move detection uses inode tracking on POSIX and SHA-256 correlation on Windows. Either way, a single move event is emitted upstream rather than a delete+create pair.
<TuxProse>
  <MDCRenderer :body="parsed.body" :data="parsed.data" />
</TuxProse>

hand-authored

Plain HTML slot

Works the same for any HTML — useful when you want the prose rhythm in a hand-rolled section without going through MDC.

Document title

Body paragraph in Open Sans, 0.9375rem, 1.75 leading. Italic emphasis reads as it should, and inline code picks up the maroon tint against the sunken surface.

Section heading

  • List items use the body face
  • With comfortable 1.75 leading
  • And generous nesting room
<TuxProse>
  <h1>Document title</h1>
  <p>Body paragraph…</p>
  <h2>Section heading</h2>
  <p>More body…</p>
</TuxProse>

wrapper tag

Non-landmark wrapper

The wrapper defaults to <article> (the correct landmark for a long-form region). Pass as="div" when the parent already provides the landmark — e.g. inside a card preview.

Inside a card

Same prose rhythm, no duplicate landmark. The classes pass through to the wrapper — combine with data-tux-elevation="rest" for the Batch J shadow tier.

<!-- Inside a card, use a non-landmark wrapper -->
<TuxProse as="div" class="border rounded-md p-5">

</TuxProse>

props

Props

  • as — wrapper tag. Defaults to "article"; pass "div" inside another landmark.
  • Default slot — any markup. Styles apply via :deep() selectors so slot content gets the rhythm regardless of authoring surface.

scope boundary

Prose vs chrome

TuxProse styles long-form content — the kind of thing an author writes in markdown. Page chrome (the header lockup, the sidebar nav, breadcrumbs, page titles) stays on the utility classes — .heading--bold, .heading--display, .eyebrow, .subhead, .link-tti. The split keeps a Vue page from accidentally pulling prose rhythm into UI scaffolding where the type sizes would feel off.