DraftLintguide
← Back to editor

User guide · Phase 1

Drafting in DraftLint

DraftLint is a contract editor that treats your document as structured law — articles, sections, clauses — not loose prose. This guide covers how to use the editor today and the underlying vocabulary you’ll see referenced in issues, PRs, and the schema.

01 Using the editor

Opening a document

The editor lives at /playground. A sample Stock Purchase Agreement loads by default so you can see numbering, outline, and signature rendering without typing anything first.

To start fresh, click New in the topbar. You get a minimal scaffold — one article with one section and one empty body paragraph. The numbering plate already reads Article 1 / Section 1, and the caret lands inside the empty paragraph ready for typing.

To switch between the bundled sample documents, click Examples in the topbar (or open the Menusheet on mobile and pick from the Examples section). Today there are three: the default Stock Purchase Agreement; a longer, more cross-reference-heavy Franchise Agreement; and a Patent License Agreement. Switching examples replaces the current document — there’s no persistence yet, so any unsaved edits in the current sample are dropped.

The Patent License Agreement is a synthetic medical-device deal (Meridian Surgical licensing a surgical retractor portfolio to Halcyon Devices). It is the densest of the three and the only one that uses all five hierarchy levels — the Net Sales definition runs article → section → subsection → clause → subclause. It is also the cleanest: no heading carries a hand-typed number, every cross-reference in the prose is a real reference rather than typed text, and every coined term is defined in Article 1 and marked at each usage. That makes it the sample to reach for when you want to watch renumbering, reference relabeling, or the Defs rail react to a change you just made.

Empty headings show muted placeholder copy — “Untitled article”, “Untitled section” — until you type into them. The placeholder is purely visual; it never enters the document text and never persists.

The document list

When you’re signed in, your saved documents live on a dashboard at /dev/editor/list. Each row is a document; click it to open that document in the editor. New document creates a fresh Untitled document and opens it straight away. From inside the editor you can return here any time with the Documents link in the topbar.

The list is separate from the /playground playground. The playground always loads a sample and keeps your work only in the browser — nothing typed there is saved. Anything you reach from the document list, by contrast, is a real saved document tied to your account.

Saved documents

Opening a document from the list takes you to /dev/editor/[id] — the same editor, but bound to that one saved document. Its title shows in the topbar and you can edit it there; the rest of the editor works exactly as it does in the playground.

This is distinct from the unsaved /playground playground: a document opened by id belongs to your account and has a stable address you can return to, while the playground is a scratch space that always starts from a sample.

Saving your work

Saving is explicit. Press S (Ctrl+S on Windows/Linux) or click the Save indicator in the topbar to write your changes. There is no autosave — nothing is persisted until you save.

The indicator tells you where you stand. It reads Saved when everything is written, flips to a Save button reading Unsaved · Save the moment you make an edit, and shows Saving… while the write is in flight. If the document was changed on another device since you opened it, it reads Changed elsewhere and saving pauses until you reload.

If you try to close the tab with unsaved changes, the browser warns you first. This applies to saved documents only — the in-memory /playground is never saved and never warns.

If your document is edited elsewhere

The same document can be open in more than one place — another tab, another device, a colleague’s screen. If someone else saves a change before you save yours, your next save can’t go through: writing it would silently overwrite their work. Instead of losing either version, the workbench stops and tells you.

You’ll see a banner across the top of the editor reading This document was changed elsewhere. Reload to continue. While the banner is up, saving is paused and the editor is locked, so you can’t pile up edits that would be thrown away. You have two choices:

  • Reload — fetch the current version from the server and pick up editing from there. Anything you typed since the last successful save is discarded.
  • Discard local changes — the same outcome, stated plainly: drop your unsaved edits and load the current version.

There is no automatic merge today — whichever copy was saved first wins, and reloading gives you that copy to continue from. If you had substantial unsaved work, copy it out (for example into a scratch document) before you reload.

Checking out a document to edit

A saved document opens read-only. To make changes, choose Check out from the mode control in the top bar — the indicator flips from ○ Viewing to ● Editing. While checked out, S saves a minor version; choosing Check in records a labelled major version and releases the document. Switch to viewing releases it without recording a version. View preferences now live under View in the top bar.

While ○ Viewing, the document is fully protected: typing does nothing, and the editing shortcuts below — Tab, B, Z, and the rest — are inert. Attempting any of them raises a Modifications are restricted in read-only mode notice with a one-click Check out button. Navigation shortcuts (find, outline nav) still work while viewing.

Your checkout survives a page reload — refresh or reopen the tab and you stay in ● Editing rather than dropping back to read-only. The reloaded document shows its last savedversion, so press S before reloading to keep recent edits. A checkout you walk away from frees itself after about 15 minutes of inactivity; until then it stays yours, and checking the document out again from another tab simply takes over your own earlier session.

Version history

Every save and every check-in mints a version. Click History in the topbar (desktop, saved documents only) to open the version-history drawer on the right of the paper. Each row shows the version number in major.minor form and a reason badge — checkin, save, or restore. The Major filter keeps only the N.0 check-in rows; All shows every version. Close the drawer with or by clicking History again.

Each row also carries a compact change badge — what that save or check-in changed versus the version before it: + added, removed, ~ amended, moved, and when a change broke a cross-reference or removed a defined term. A legend under the list spells the glyphs out. When you pick two versions to compare (the Compare toggle, then click a base and a revised), the same summary previews the selected pair beside Compare →before you open the full redline. Renumbering alone isn’t shown — it’s a mechanical side-effect of adding or removing sections.

Previewing a version.Click any row to render that version’s body read-only in the paper — a notice bar at the top reads Previewing N.M · read only. The live editing session is never touched; clicking Exit preview in the banner restores your live editor exactly as you left it. Clicking a different row while in preview loads that version instead.

Restoring a version. While you hold the checkout (the mode control reads ● Editing), an active previewed row gains a Restore button. Confirming the dialog writes the chosen body as a new minor version with reason restore — history is never rewritten, and the new version is the only one you need to audit. After a restore, the editor loads the recovered body and the save indicator reads Saved immediately — the server etag was adopted along with the body, so the next S goes through without a conflict. If you had unsaved edits, the confirm dialog warns you that they will be discarded.

Comparing two versions

From the same version-history drawer you can compare any two versions side by side. Turn on the Compare toggle to put the drawer in select mode, then click two rows: the first click is the base, the second is the revised version. Clicking a selected row again clears it; clicking a third version drops your earlier pick (the base), makes your previous pick the new base, and sets the third as the revised version. A sticky footer shows your picks as base → revised with a Compare → button that enables once both are chosen. The Major / All filter scopes which versions you can select; it defaults to Major.

Compare → enters a read-only compare mode that replaces the editor with a structural redline of what changed between the two versions — clauses added, removed, moved, renumbered, and amended. A sub-bar across the top shows the version route, the change counts, and an exit . Compare mode is read-only: you can read the differences but you can’t accept or reject them here. To accept or reject redline changes, edit a checked-out document with the live redline instead (see Tracking changes (Redline) below). Pressing the sub-bar leaves compare mode and returns you to the editor unchanged.

The structural rail carries a filled viewport boxmarking where you are in the document — drag it to scrub. The sub-bar’s ↑ x/y ↓ control (or Alt+↑ / Alt+↓) steps to the previous or next change — added, removed, moved, or amended — and stops at the first and last.

The control on the sub-bar widens the structural rail into a scaled minimap: every clause becomes a row with a bar whose height tracks the clause’s length, coloured by how it changed, with a change tick and the clause name (renumbered clauses show old → new). Moved clauses draw an arc in the left gutter from where they were to where they landed. Press again to collapse back to the thin rail. Your choice is remembered. When pinned, the integrity report folds away to keep the minimap roomy — reopen it any time from the Integrity ▾ chip on the sub-bar.

On a phone, tap Menu and choose Version history to reach the same picker — turn on Compare, tap the two versions, then Compare →. In compare mode the structural rail becomes a horizontal strip under the sub-bar — tap a coloured segment to jump to that change, or drag the box to scrub through the document. Integrity findings and a list of every changed clause live in the bottom tab bar under Changes and Integrity; tap a change to jump to it. A moved clause is marked with a moved badge.

To follow a single clause instead of the whole document, open its history — press and hold (or right-click) the clause in the document, or press and hold its row in the outline, and choose View history. A panel shows that clause across the document’s versions, newest first: each turn where it changed, with the wording added and deleted marked inline against the previous version. Stretches where the clause held steady collapse into an unchanged 6.0–8.0 (3) divider you can expand. The Major / All toggle scopes which versions count, the same as version history.

That press-and-hold (or right-click) menu is the clause’s action menu — besides View history it offers Delete clause and Promote / Demote to change its level, and, while the Redline lens is on, Accept / Reject changes for the whole clause. When the press lands on an undefined word — one not already a definition, usage, or phantom-detected span — the menu leads with Define “word”…, which opens the define-term popover pre-filled with that word.

Tracking changes (Redline)

Check the document out to edit, then turn on the Redline toggle from the View ▾ menu. The editor diffs your working draft against the version as it stood when you checked out and shows the changes inline — added text underlined, deletions struck through and kept visible, moved and renumbered clauses tagged. You keep editing normally; the redline trails your typing by a moment and catches up when you pause.

While the lens is on, the analytical highlights (legal lens, defined-term and usage hints) step aside so the changes read cleanly, but cross-references stay clickable and you can still jump to a definition. Check in to snapshot the draft as a new version.

You review changes at three levels — a single word, a whole clause, or the whole document.

Clause. Every changed clause shows a small / pair in the left margin, level with its heading, the whole time the lens is on — you don’t have to hover to find it. Click to accept the clause’s change or to reject it (accepting an added, removed, moved, or edited clause settles it; rejecting puts it back the way it was at checkout). You can also right-click a change to open a menu with the same choices — and on a touch device, long-press a change to open that menu. A renumbered clause has no control of its own: it follows automatically from whatever structural change caused the renumbering, so it is never counted as a change of its own.

Word. To settle one inserted or deleted word on its own, hover that word on a desktop and a smaller / pair appears just above it. A word swapped for another (a deletion and an insertion in the same spot) is one change, not two: accepting or rejecting either half settles the whole swap, so you never have to clear the old word and the new one separately. The menu (right-click, or long-press on a touch device) also offers Accept all in clause / Reject all in clause, which settle every change in that clause at once.

Document. A sticky review bar sits at the top of the page while the lens is on, showing how many changes are still open and offering Accept all / Reject all for the whole document. The bar hides itself once there is nothing left to review. The same two verbs live in the Actions ▾ menu on a desktop and in the Menu sheet on mobile, each shown on the same terms as the bar — while the redline lens is on, you are checked out, and there is at least one open change to settle. Because they touch the entire document, the doc-level verbs ask you to confirm first.

These decisions are permanent at every level: accept advances the checkout baseline and reject discards the edit, and neither is undoable with Z — which is why Accept all / Reject all go behind a confirmation. The accept/reject affordances appear only while you are checked out with the redline lens on.

The Redline toggle is disabled when you are not checked out — the lens diffs against the checkout baseline, so it only makes sense while editing.

Deleting a document

You can delete a saved document from two places. In the document list, hover (or focus) a row and click the × on the right. In the editor, open the document-actions menu in the topbar and choose Delete document. Either way, a confirmation dialog asks you to confirm before anything happens — Cancel or Escape backs out.

Confirming from the list removes the row right away. Confirming from the editor takes you back to /dev/editor/list. The delete is a soft delete: the document drops out of your list but is not erased, so support can recover it until a future trash feature lets you do so yourself.

Exporting to Word

Saved documents can be downloaded as a .docx file. On desktop, open the document-actions menu in the topbar and choose Export to Word; on mobile, open the Menusheet and tap the same row. The download starts right away, named after the document’s title (falling back to Untitled.docx for a blank one).

If you have unsaved edits — or an accepted redline change that hasn’t been saved yet — exporting saves them first, so the file you get matches what’s on screen rather than the last save. Numbering (Article/Section/etc.) is emitted as real Word multilevel-list numbering rather than literal text, so inserting or deleting a section in Word renumbers the rest for you. Lettered levels use Word’s own letter sequence, so a label reads the same on screen and in the exported file however many siblings a group has. Export isn’t available in the in-memory playground — it needs a saved document to generate from.

Signing in

/playground and /dev/editor/compare are open to everyone, signed in or not — both are in-memory-only surfaces, so there’s nothing tied to an account to protect. Saved documents are the gated surface: opening /dev/editor/list or a saved document by id while signed out redirects you to /sign-in; once signed in, you land back where you tried to go.

The far right of the workbench topbar shows Sign inwhen you’re signed out and a user avatar (with a dropdown for account settings + sign out) when you’re signed in. Sign-in and sign-up live at /sign-in and /sign-up. Sign-out drops you back at the marketing landing page.

The workspace

Three regions, top to bottom and left to right:

  • Topbar — the masthead. Wordmark on the left, then an Actions dropdown (New document, Find & replace, Scan refs) and the Examples menu. After those come the destination links — Documents, Compare, Patents, Charts, and Dictionary. They fit themselves to the space the window leaves them: the ones that no longer fit move into a More ▾ menu, which sits immediately after the last link that still fits. Dictionary folds first and Documents last, and a folded destination opens from the menu as the same link. Widen the window and they come back out. A saved document you have checked out carries more topbar controls — the checkout state, the save indicator, History — so fewer destinations stay in the row there than on the playground; at a typical laptop width you may see only the first one or two, with the rest under More ▾. View preferences on the right now live together under a single View ▾ menu — a column-width toggle (Reading ⇄ Full), a Numbering choice (five schemes — see Reference), a Lens choice, a Redlinetoggle (available only while checked out for editing — see “Tracking changes” below), and a Theme choice (Auto / Light / Dark). For saved documents, a History toggle sits beside the View ▾ menu; pressing it opens the version-history drawer on the right of the paper (desktop only). The Guide button is at the far right. Reading width is the default; Full lets the document fill the column for wide tables or side-by-side review. Theme persists per-browser (defaults to Light).
  • Format bar — pinned below the topbar, in three zones. Nav + history on the left (Back / Forward / Undo / Redo); a live breadcrumb in the center showing the section your caret is in (click it to recenter on that section); and the inline-formatting marks (B / I / U) on the right.
  • Outline rail— a live table of contents on the left. Click any entry to jump to its heading. Every jump — from the outline, the breadcrumb, a cross-reference, or Back / Forward — centers its target in the viewport and gives it a brief highlight so it’s easy to spot. The active item highlights as you scroll or move the caret. Drag the rail’s right edge to resize it (or focus the handle and press / , hold Shift for larger steps). Double-click the edge — or press Homewhile it’s focused — to reset to the default width. Your chosen width persists per browser.
  • Paper — the document surface itself, with a statline below reporting article count, section count, word count, and the active numbering scheme.

On mobile

At viewport widths up to 720 pixels (most phones in portrait), the workbench swaps to a chrome shaped for one-thumb operation. The document stays the product; controls are summoned when needed and tuck away otherwise. Every panel and command from the desktop workspace is still reachable.

Slim topbar and Menu sheet

The topbar shrinks to the DraftLint wordmark on the left and a single Menu trigger on the right. Tapping Menu raises a sheet from the bottom of the viewport holding New, Find, Scan refs, the Guide link, the numbering-scheme options, the Legal Lens toggle, and the theme toggle. Dismiss by tapping the scrim or the Close link, pressing Esc, or grabbing the handle at the top of the sheet and swiping down.

Bottom rail tray

The four rail panels live in a persistent 32-pixel tab strip pinned to the bottom of the viewport — Outline · Defs · Refs · Legal. Tapping a tab raises a sheet covering roughly the bottom two-thirds of the viewport with the corresponding panel; the same tab strip is mirrored at the top of the sheet so you can switch panels without dismissing. Close the sheet by tapping the active tab again, tapping the scrim or the Close link, pressing Esc, or swiping the handle at the top of the sheet down. Navigation actions inside a panel (jumping to a heading, a definition, a usage, a cross-reference target, or a legal term) close the sheet automatically so you land back on the document.

Selection-anchored format toolbar

The format toolbar is hidden when the caret has no range — fresh cursor, nothing to format. The moment you select text, the B / I / U cluster appears at the top of the document; collapsing the selection back to a caret hides it again. The paper-width and numbering-scheme toggles don’t appear in the mobile toolbar: paper width is locked to Reading on mobile, and the numbering scheme lives in the Menu sheet. If you had Full set on desktop, resizing the viewport back above 720 pixels restores it automatically.

Find dock

The find-and-replace panel docks to the viewport bottom on mobile (above the rail tab strip), where the on-screen keyboard can’t push it out of view. Everything inside the panel — query input, replace input, scope selector, match navigation — behaves exactly the same as on desktop.

Double-tap actions

Double-tapping does different things depending on what’s under the tap:

  • A cross-referencejumps to its target — the same destination the inspector’s Jump to targetbutton reaches, without opening the inspector first. The context bar’s Back button returns you.
  • A legal term-of-art(a phrase the dictionary recognizes — “consideration”, “force majeure”, etc.) opens the term inspector with the dictionary entry. Placing the caret inside the term (a click or a single tap) opens the same card; double-tap is the explicit gesture that works even when the tap leaves the caret elsewhere.
  • A defined-term usage views its definition without moving the caret — if the term is also a legal term-of-art it pops the term inspector, otherwise it scrolls to and briefly highlights the in-document definition. (This is the View definition item from its long-press menu.)
  • A definition views its first usage — scrolls to and briefly highlights the first occurrence. (The View first usage item from its long-press menu.)
  • A phantom-detected span— a capitalized phrase that looks like it might be a defined term but isn’t — offers a single Define this term action that opens the define-term popover pre-filled.
  • Any other word in the prose does nothing on double-tap — to define it, long-press (or right-click) and choose Define “word”… from the clause menu.

Double-tap is the default action; long-press opens the full action menu for whatever’s under it (see below).

Long-press to open the action menu

Hold your finger on a marked span for about half a second to open a small action menu anchored to it. The menu’s items vary by what you long-pressed:

  • A definition: View first usage, Jump to first usage, Jump to next usage, Jump to last usage, Rename, Remove definition.
  • A usage: View definition, Jump to definition, Jump to next usage, Jump to last usage, Rename.
  • A cross-reference: View target, Jump to target, Re-target… (reopens the cross-reference picker over the existing link so you can point it elsewhere or change its format), and Remove cross-reference.
  • A broken cross-reference (its target no longer exists): Why is this broken? (opens the inspector explaining the breakage), Re-target…, and Remove cross-reference.
  • A phantom-detected span: Define this term.
  • Plain prose (no marked span): the clause context menu for the surrounding clause. When the press lands on an undefined word, the menu leads with Define “word”…, which opens the define-term popover pre-filled.

View … items bring the target into view without moving the caret — for terms they scroll to and briefly highlight the span; for a cross-reference they scroll to the destination node. One exception: when the usage you long-pressed is also a legal term of art (one of the dictionary-matched spans), View definitionpops the Term Inspector with that term’s dictionary definition in place, rather than scrolling to the in-document definition — Jump to definition still navigates there. Useful when you want to glance at something without losing your typing position. Jump … items move the caret to the target. Rename, Remove …, and Re-target… close the menu on confirm.

Dismiss the action menu with the × button, a sideways swipe on the handle, a tap outside, or Esc.

First-visit hint

On the first mobile visit per browser session, a small card floats above the document listing the core gestures (double-tap, long-press, press-and-drag to cite, swipe, context bar). Dismiss it with the × or the Got it button — the dismissal sticks for the rest of the session, but the card returns on the next one so a returning user gets a quiet refresher.

Section breadcrumb

On a long doc, the outline isn’t visible without raising the rail sheet — so a thin breadcrumb pins itself to the top of the viewport as you scroll, showing your current article, section, and heading. Tap it to open the rail sheet directly to the Outline tab. It hides when you make a selection (the format toolbar takes the same slot) and at the very top of the document, before you’ve entered any hierarchy node.

Context bar

Sitting just above the rail tab strip, a 40px bar holds Back, Forward, and Undo. Back and Forward step through the navigation stack — every jump from the outline, a definition, a usage, a cross-reference, or a legal term records the position you were leaving, so Back returns you to it. On desktop, and step back and forward through that same navigation stack (they fall through to the normal line-start / line-end motion when there’s nowhere left to go). Undo reverses the most recent edit (the same action as Z on desktop). The bar tucks away when a sheet, the find dock, or the format toolbar takes over, and auto-hides while you scroll down the document — flick up or return to the top of the page to bring it back.

Reshaping structure

The depth of a heading is a property of the document, not a font size. Use Tab to push the current node one level deeper into the previous peer, and ShiftTab to lift it out. Numbering renumbers immediately. If a move would violate the schema (for example, trying to nest below subclause), the keystroke is silently absorbed — nothing happens to the document.

To reorder siblings at the same level, place the caret inside the node and press Alt or Alt. This moves the entire subtree, headings and children together.

Adding new sections inline

Enter behaves differently depending on where the caret sits in a heading:

  • At the endof a heading, the caret moves forward into the body — the first paragraph of the current section (or the first nested child’s heading at higher levels). No new section is created; this is the “finish the title, start writing” path.
  • In the middle, the heading splits — the remainder text moves into a new sibling at the same level and the caret follows.
  • At the start, an empty sibling is inserted before; the caret stays put.

To create a brand-new sibling at the same level after you’ve already dropped into the body, press Enter. That works from anywhere inside an article / section / subsection / clause / subclause and lands the caret in the new heading. Numbering reflows on its own.

Deleting a section

Two paths, same effect: while the caret is inside the section’s heading, or hover the row in the Outline rail and click the ×button that appears on the right. Children go with the parent — deleting a section takes its subsections, clauses, and subclauses along. The outline’s × is an editing affordance — while ○ Viewingit is hidden, since a read-only document can’t be mutated. Check out to bring it back.

A toast at the bottom of the page confirms the delete and offers Undo (or just Z). Cross-references that pointed at the deleted node turn into broken refs — the red squiggly underline + Refs-rail Broken section surface them. No confirmation dialog; the toast + undo carry the safety.

The schema requires at least one section per article (and the doc requires at least one article). When deleting would leave a required-non-empty parent empty, the command is a silent no-op. One known limitation: once you delete and save, the node’s stable id is gone for good — recreating the section by hand won’t bring back cross-references that used to point at it. Undo restores it; save-then-undo doesn’t.

Inline formatting

Bold, italic, and underline are the supported inline marks for prose formatting. Toggle them with the toolbar or with B / I / U. The defined-term mark is documented separately below.

The toolbar stays pinned to the top of the viewport as you scroll, and on desktop also carries history + navigation buttons — ‹ Back, Forward ›, Undo, and Redo. Back and Forward step through the navigation stack ( / ); Undo and Redo are the editing stack (Z / ShiftZ). Each greys out when there’s nothing to go to, and hovering any of them shows its shortcut. (On mobile these live in the context bar instead.)

Defining terms

Select the text you want to define — typically the quoted, capitalized phrase right after “means” — and press ShiftD. A small popover appears in the right edge of the document with the selected text pre-filled as the canonical term. Edit it if the canonical form differs from what you selected (for example, selection “Affiliates” with canonical term Affiliate), then press Enter or click Define to wrap the selection. Esc or Cancel dismisses without changes. Definitions render in a brilliant midnight-blue ink, heavy weight, small-caps; in-prose usages of the same term echo the chord at a lighter weight in soft midnight ink — no underline, so the term-network reads at a skim without fragmenting the surrounding prose.

Automatic usage binding

The editor watches for capitalized phrases that match a registered canonical term and acts on its own when the choice is unambiguous:

  • Exactly one definition — the match is wrapped in a definedTermmark silently. The Defs rail’s usage count ticks up; nothing pops over the prose. The auto-bind is its own undo step, so Z reverts just the bind without erasing the word you typed.
  • Zero or two-plus definitions — the match gets a faint dotted underline in muted ink (distinct from the numbering-blue phantom underline). Hover or Tab onto the underline to surface a small Bind as usage of “X” pill; Enter or click confirms the binding.Esc dismisses the pill; the underline stays for the next interaction. Auto-binding is held back here because silent binding could introduce the wrong cross-reference.

Behavior is not retroactive: adding a second definition of an already-bound term leaves existing usages alone. Remove the conflicting definition and subsequent matches resume auto-binding.

Jumping from a usage to its definition

click on any defined-term usage moves the caret to the first definition mark for the same term. Same gesture as click on an xref. Use Ctrlclick on Windows/Linux. Plain click stays a normal selection; only the modifier triggers the jump.

Marking usages manually

Once a term is defined, you can mark later references to it as usages so the Defs rail counts them and rename-cascade picks them up. Select the reference and press ShiftK. A picker appears listing every canonical term in the document, alphabetically. Type to filter, / to move the highlight, Enter to commit, Escto cancel. If the selection text matches a canonical term exactly (case-sensitive), that row is pre-selected — so the common case is “select the word, hit ShiftK, hit Enter.” The picker is keyboard-first; there’s no toolbar entry yet (the command palette will host one in a later phase). With no definitions in the document the picker shows an empty state pointing back at ShiftD.

Active term highlight

When the caret sits inside a definition or usage, the active span picks up a saturated green highlight and every sibling — the canonical definition and all other usages of the same term — picks up a lighter shade of the same hue. Move the caret away and every highlight disappears; defined terms read as normal prose at rest. The effect makes it possible to audit a term’s reach from the prose itself, without leaving for the Defs rail.

With the caret on any span, Shift jumps to the next occurrence of the same canonical term and Shiftjumps to the previous; both wrap at the ends. The definition is part of the cycle at its document position. The same gesture works on terms-of-art spans — see the § 02 keymap. When the caret is not on a qualifying span the default selection-extending motion runs as before. If a span happens to be both an authored defined-term and a dictionary term-of-art, the defined-term cycle wins.

Cross-references

Press ShiftRto open the cross-reference picker. The picker lists every article and section (and clause / subclause as the doc deepens) in document order, each row showing the label that row’s scheme computes — 1.2 under Bare section, Section 2 under Default — and the first ~60 characters of the heading text. Arrow keys move the highlight; Enter commits; Esc cancels. Typing in the input filters by either the label or the heading text (substring, case-insensitive).

Three formats. Under the Default scheme, a reference to subsection (b) of the second section of Article 1 reads Long (Article 1, Section 2(b)), Short (Art. 1, §2(b)), or Number-only (2(b)). The default is Long; your selection is remembered for the rest of the browser session.

Number-only is deliberately the bare number, not the whole chain with its words removed. Choosing it says the context is already clear on the page; 1, 2(b) would match no citation convention. If you need the reference to stand on its own, Long and Short are the two that carry the article.

A reference names as much of the hierarchy as it needs to be unambiguous, and that depends on the numbering scheme. Where a section number already carries its article — Bare section’s 4.2 — the reference is just that. Where sections restart their count inside each article, as under the Default and Bylaws schemes, a bare Section 2 would name one section per article, so the reference names the article as well.

Which end it starts from follows the scheme’s own citation habit. The Default scheme leads with the article — Article 1, Section 2(b), shortening to Art. 1, §2(b). Bylaws put the cited section first and the article behind a preposition: Section 2(b) of Article I, shortening to §2(b) of Art. I. Both are ordinary legal usage; the scheme picks the one its house style uses, and switching schemes rewrites every reference accordingly, in the same transaction as the renumber.

Typing still works the short way. The tab-to-bind suggestion and Scan for references both recognize Section 2(b) written on its own — you are not expected to type the article prefix to get a match.

With an empty caret, confirming the picker inserts the computed text wrapped in an xrefmark. With a non-empty selection, confirming wraps the existing text as an xref without changing it — the path for converting prose like “the foregoing Section” into a tracked reference.

Drag to cite

Each row in the Outline rail has a small grip () — on desktop it appears on hover, just left of the delete ×. Drag it into the document and drop it where you want the citation: a thin caret line tracks the drop point as you move (snapping to word boundaries so the reference never lands mid-word), and releasing inserts an xref to that node — the same result as running the picker at the caret, in one gesture. If the spot you want is off-screen, drag toward the top or bottom edge and the document scrolls to follow — faster the closer you get to the edge. The drop uses your last-used format; a toast offers Change format, which re-opens the picker over the just-inserted reference. The grip is a pointer affordance — ShiftR remains the keyboard and screen-reader path. Like the delete ×, the grip is editing-only: while ○ Viewing it is hidden, since dropping a citation would mutate a read-only document.

On mobile the grip is hidden — the glyph is too small to be a comfortable touch target, and a press-and-hold drag reads poorly on touch. Insert a cross-reference from the picker (ShiftR) instead. Outline rows still tap to navigate.

Tab-to-bind suggestion

As you type a citation that resolves unambiguously to a single hierarchy node — Section 4.2, §4.2(b), Article III, abbreviations like Sec.— the matched text picks up a dashed blue underline and a small chip appears just after it previewing the target’s heading and a Tab hint. Press Tab (or click the chip) to commit the binding in a single undo step — separate from the typing transactions beneath it, so undo reverts just the bind and leaves your prose alone. Esc, moving the caret out of the matched range, or typing past the citation dismisses the suggestion silently. Only confident, unambiguous matches surface — when the resolver isn’t sure, the chip stays out of your way and ShiftR is the explicit path.

In the body, xrefs render as a thin blue underline (same hue as the numbering plates — they encode the same kind of structural identity). When the caret sits inside one, the underline strengthens. clickon an xref jumps the caret to its target’s heading (use Ctrlclick on Windows/Linux); plain click stays a normal selection, matching the defined-term gesture. If the target was renamed or removed, the underline turns into a bright-red squiggle (same shape spellcheck uses), and click flashes the source span instead of jumping anywhere — a visible hint that the reference is broken and needs the picker re-run.

When you add, remove, or reorder a section — or flip the numbering scheme — every xref’s visible text updates in the same transaction. There’s no separate refresh step and no flicker; the renumber and the relabel land together, and a single undo reverts both. Xrefs whose target has gone missing read as a loud [broken ref]placeholder paired with the red squiggly underline; the rail’s Broken section keeps tabs on each one by id so you can find and re-point it. Same-transaction salvage still runs first: if your structural change happens to mint a section whose computed label uniquely matches the xref’s current text, the xref silently rebinds to the new node before the placeholder kicks in. Ambiguous matches stay broken on purpose. Undo always reverts the placeholder swap together with the structural change that triggered it.

Place the caret inside an xref (click it, or arrow into it) and a small card surfaces with the target’s full label, its heading text, and the first sentence of its body — along with a Jump to target button that works the same as clickon the underline. The card stays open while the caret is inside the xref — including while you type — and closes when the caret leaves. Alt-click shows the card without moving the caret. Broken references show a muted “Target not found” card with a pointer back to ShiftR for retargeting. Press Esc (or the × button) to close the card early; it stays closed until the caret leaves the xref and returns.

Scan refs

The topbar’s Scan refs button finds plaintext citations anywhere in the document — Section 4.2, §§ 1, 2, and 3, Sections 4.2 through 4.5, Article III, parenthesized sub-locators, and the common abbreviations — and routes each match through a review dialog. Each row shows the surface text, the resolver’s best-guess target, and a confidence chip (confident, fuzzy, or no match). Confident + fuzzy rows are checked by default; no-match rows must be overridden via the row’s ⋯ menu before they can apply. Confirming binds every accepted row in a single transaction — one undo step regardless of how many references the scan caught. The scan only surfaces unbound plaintext; spans already wearing an xref mark are skipped.

The Defs rail

The left rail has three tabs: Outline, Defs, and Legal. Switching tabs preserves the outline state — collapsed sections, focus, and scroll position survive the round trip.

The Defs tab lists every defined term alphabetically. Each row shows:

  • Term — the canonical string carried by the mark.
  • Usage count — number of definedTerm marks pointing at this term. (Auto-suggested usages land in a later story; today this counts only usages that already carry the mark.)
  • Snippet — the marked text from the first definition, italicized and muted.
  • State stripe — a 2px right-edge stripe encoding state: muted for dead (defined but never used), numbering blue for phantom (placeholder for the upcoming detection pass), warning red for conflict (same term defined more than once).

Clicking a row jumps the caret to the first definition. The kebab () opens a per-term menu with Jump to next usage and Rename term….

A filter strip at the top of the rail — All / Defined / Phantom— narrows the list. Each chip carries its own count. Defined hides phantoms (so you can audit just the terms with bindings); Phantom hides everything else (so you can triage the “did you forget to define this?” flags in isolation).

Healthy defined-term rows wear a leading 3px midnight-blue marker and render the term itself in the same midnight ink at a heavier weight — the rail reads as every term is anchored, not as “one row out of a quiet list.” The row the caret currently sits inside picks up a saturated wash + an outer glow ring. Dead and phantom rows opt out of the accent so the chord is reserved for terms that actually carry a binding.

Renaming a term

Rename term… opens a preview dialog: the header holds a new-term input, and the body lists every marked surface form of the old term (one row per unique form, most-common first). Each row carries an editable suggested replacement and a Skip toggle. Enter from the header commits; Esccancels with no changes. Apply runs every selected row’s text rewrite and re-attributes every mark — including skipped spans, whose visible text stays but whose term attribute still updates — in a single transaction (one undo step).

Smart-suggest fills in confident transformations only:

  • Caseaffiliate subsidiary, Affiliate Subsidiary, AFFILIATE SUBSIDIARY.
  • PossessiveAffiliate’s Subsidiary’s.
  • PluralAffiliates Subsidiaries. Powered by the pluralize package so irregulars like Indices and Counsel come out right.

Anything else — verb / adjective derivations (Affiliated, Affiliation), quoted forms (“Affiliate”), multi-word phrases — is left blank-and-not-confident on purpose. The row defaults to Skip; type your own replacement and untick Skip to apply. Better to type than to accept a wrong suggestion in haste.

If the new term you type is already defined elsewhere in the document, Apply is blocked with an inline error so you can’t accidentally create a conflict. Phantoms (capitalized matches with no definition mark) are not touched by rename — only marked spans for the renamed term are.

When every span happens to be an exact-case match of the old term (the common case after defining a clean canonical form), the command-palette / programmatic rename path skips the dialog and applies silently. The rail kebab always opens the dialog so you can see what changed.

Footer totals follow the rhythm N TERMS · N DEAD · N PHANTOM · N CONFLICT in mono uppercase — handy as a glanceable health indicator while drafting.

Your term library

Every account has a personal library of defined terms that layers on top of DraftLint’s built-in terms-of-art dictionary (see “Legal-term recognition” in the Reference section below). A term can be recognized in more than one of these layers at once, so the editor always names which one is answering— the one whose definition you’re actually looking at — in a fixed precedence order:

  1. Defined in this document — a ShiftD definition in the open document always wins, exactly as it did before the library existed.
  2. Your library— an entry you’ve saved to your account, if the document has no local definition of its own.
  3. Terms of art — the built-in baseline, when neither of the above applies.

Nothing is silently overridden: when a lower layer also has an entry for the same term, the Term Inspector card (below) shows the answering layer’s definition up top and the shadowed lower-layer entry underneath, in a collapsed Also in … row you can open.

Promoting a term from a document

The library grows out of real drafting, not a separate form. Wherever you can see a defined term, there’s a way to save it:

  • In the Defs rail (above), each row carries a Save button next to its term.
  • In the ShiftD popover, once a definition lands the success state offers Save to library alongside Done.

Either path opens a small dialog pre-filled from the document: the term from the definition mark, and a definition seeded from the text of the block that defines it — honestly labeled as a starting point, not a final answer, and fully editable before you save. Add optional variants (comma-separated) and pick a tier: only Negotiated and Drafting convention are on offer here. Hard (statutory) and Semi-rigidstay reserved for DraftLint’s curated terms-of-art dictionary — your library can’t promote into those tiers, in the UI or at the API.

If the term is already in your library (matched on a normalized key, so case and punctuation don’t create duplicates), saving again doesn’t fail or silently overwrite — the dialog switches to a compare view, showing the currently-saved definition beside the one from this document, with Replace definition to update it or Cancelto leave it alone. A term already saved shows a checkmark instead of the Save affordance, both on the rail row and in the popover’s success state.

Managing your library at /dictionary

The Dictionarylink in the topbar opens your library’s management page. Dictionary is the first destination to fold, so on a narrower window it is reached from the More ▾menu rather than from the bar itself (see “The workspace” above). The page lists every entry — term, tier badge, definition preview, and, for a promoted entry, a provenance line naming the document it came from. Search narrows the list as you type, across terms, variants, and definitions; a tier filter (All / Negotiated / Convention) narrows it further. Click a row to edit it in place — term, variants, tier, definition, and an optional watch note — or add an entry by hand from the + Add a term form at the bottom, for terms you want in your library without having drafted them yet. Deleting a term shows an undo toast rather than a confirm dialog; the window to undo closes after a few seconds.

Library changes apply live

Saving a term updates every open document’s markup right away — no reopen needed. Promote one from a document you already have open, or add or edit one on /dictionary, and the badge and the markup both update in place. The one exception: a term you promote never retroactively relabels anything in the samedocument you promoted it from — its own in-document definition already outranks the library for that term, so there’s nothing to relabel there. Any other open document, in this tab or another, picks up the change; a change made on /dictionary in a different tab arrives with a brief delay while that tab notices and refetches. Leaving a document to visit /dictionary and coming back works too: the editor re-checks your library every time it opens, so a term you added while you were away is already marked up when you return — no reload needed.

Phantom detection

A phantom is a phrase that looks like a defined term but has no matching definition. The rail flags three patterns:

  • Quoted capitalized phrases “Affiliate” used without a definition. The strongest signal; legal drafting almost always quotes a term where it is defined.
  • Multi-word capitalized sequences Material Adverse Effect mid-sentence with no definition.
  • Single capitalized words mid-sentence each Borrower where Borrowerisn’t defined. Sentence-initial capitalization, all-caps acronyms (LLC), and a small stoplist of unambiguous proper nouns (US states, months, days, common country names) are suppressed.

Phantoms surface as rows with a numbering-blue right-edge stripe and the snippet unresolved usage. Clicking a phantom row jumps to the first occurrence so you can wrap it as a definition with ShiftD or accept it as expected prose. The heuristic intentionally favors false negatives over false positives — when in doubt, it stays quiet.

Not yet shipped:per-document dismissal of phantoms (so “Closing” doesn’t keep nagging you on a doc that uses it casually) and the section-gutter stripe coordination with the gutter feature in Epic 1.6.

The Legal rail

The Legal tab inventories every dictionary term the editor recognizes in the current doc, grouped by rigidity tier in the order Hard → Semi-rigid → Negotiated → Convention. Empty tiers are omitted, so a contract that never touches a Hard term simply skips that section.

Each section header carries a tier dot in the tier’s hue and a count summary in the rhythm N TERMS · N USES. Each row shows the same dot, the canonical term, and a tabular usage count. Clicking a row jumps the caret to the term’s first occurrence; because the rigidity plugin already promotes the caret-adjacent match to .dl-rigidity--current, the jump doubles as a flash without a separate animation.

Where the Defs tab lists terms you have defined in the document via ShiftD, the Legal tab lists terms drawn from the built-in M&A dictionary — the same entries that drive the per-tier underlines and the Term Inspector. Empty state links to the dictionary section of this guide.

Pasting from Word and Google Docs

When you paste HTML from Word or Google Docs, the editor strips inline styles, spans, and image tags, then promotes paragraphs styled as headings (Word’s MsoHeading, Docs’ title) up to real heading nodes. Tables, images, and footnotes are dropped in Phase 1. Plain-text paste splits on blank lines into paragraphs.

Find and replace

Press F or click Find in the topbar to open the find panel above the document. Type a query and every hit is highlighted; the active match is emphasized and scrolled into view. G cycles to the next match, ShiftG to the previous one. Esc closes the panel, clears the highlights, and returns focus to the editor.

Three scopes are available, selected from the segmented control in the panel:

  • Whole document — the default. Matches everywhere in the doc.
  • Current section — narrows to the nearest ancestor section of the caret. Moving the caret to a different section updates the scope automatically.
  • Selection — locks to the selection range that was active when you chose this scope. Useful for replacing inside a specific clause without touching the rest of the document.

Two option toggles sit beside the scopes: Aa for case-sensitive matching and ab| for whole-word matching. Both can be combined with any scope.

The lower row holds a replacement input plus Replace and Replace all. Replace swaps the active match and advances; Replace all rewrites every match in the current scope in a single, undoable transaction. Replacements always stay inside a single block, so node boundaries (headings, paragraphs, list items) are never crossed.

Accessibility & assistive tech

The editor surface, outline, and find panel are designed for keyboard-only and screen-reader use:

  • Each heading in the document carries an aria-levelmatching its schema depth — article = 1, section = 2, subsection = 3, clause = 4, subclause = 5 — so a screen reader announces “heading level 2” for a section, regardless of how the heading is rendered visually.
  • The outline rail is exposed as a real ARIA tree (role="tree", role="treeitem",aria-level, aria-expanded). Only one item is in the tab order at a time; arrow keys move focus inside the tree.
  • Focus rings are always visible. Closing the find panel with Escreturns focus to the document so you don’t land back at the top of the page.
  • No focus traps: Tab moves through the topbar, toolbar, outline, document, and signature block in source order.

Screen-reader walkthrough

The following flow has been verified manually with NVDA 2024 on Windows / Firefox and VoiceOver on macOS / Safari:

  1. Land on /playground. The page title is read first, then the topbar landmark, then the document outline tree.
  2. Tabinto the outline. The first article is announced as “Agreement, treeitem, level 1, expanded.” walks down the visible items; on an expanded item collapses it (“collapsed” is announced).
  3. Press Enteron any treeitem to jump the caret into that heading in the editor. Type-ahead works too — pressing “s-i-g” in quick succession jumps to the next heading whose text starts with “sig”.
  4. In the editor, headings are announced with their schema-derived level. Pressing F opens the find panel; the find input is auto-focused. Esc closes it and returns focus to the document — the screen reader picks up reading from the caret.

Signature block

The footer of the sample document renders a real signature block: party name, authorized-signature rule, and date rule, laid out on a grid. The party name is editable; the rules are visual chrome and aren’t part of the document text.

Comparing versions

The Compareaction in the topbar opens a read-only structural redline of two versions of a document. Compare mode is the editor with its analysis lenses swapped for the diff lens: the legal terms-of-art, defined-term, and live cross-reference decorations are turned off so the changes stand on their own — section numbering stays, since you need it to read a redline. The body marks each changed clause with its class — added, removed (struck through inline, as a legal redline expects), moved, renumbered (a small chip showing the old → new label), or amended — with the intra-clause edits called out as underline-add / strikethrough-del. A vertical structural ribbon to the left of the paper gives a minimap of the changes; for any moved clause it draws an SVG arc from where the clause used to be to where it landed, with certainty — the durable node id makes that line a fact, not a guess. Hover a ribbon segment to spot its clause in the body; click to jump to it. A right-rail integrity panelsurfaces the findings the body deliberately doesn’t decorate: cross-references that broke or that were relabeled by an auto-update, and defined terms that were renamed or removed (with their orphaned usages flagged). Each finding is clickable and reveals the source clause. A small picker in the bar swaps between sample compare pairs.

Runs of contiguous unchanged sections inside an article collapse by default into a single mono “Nunchanged sections” widget — click to expand, click again to fold. The redline’s value is thechanges; context is one tap away.

Patent viewer (preview)

Reach it from the workbench topbar's “Patents” link, or the same entry in the mobile menu.

/patents/<publication>renders a published patent read-only: a pure reading column — the sectioned specification with paragraph numbers, the abstract, and the claim set with each claim's dependency links — alongside a reference rail with three tabs: Numerals, Figures, and Claims, each tab label carrying a live count (“Numerals 33”). Below roughly 832px wide the rail is a draggable bottom sheet with three detents — a collapsed tab bar, a half-height view, and a full-height view — that snaps to the nearest one on drag release, or cycles bar → half → full on tap; at that width and up it docks as a sticky sidebar beside the reading column instead, with no sheet chrome. In-prose FIG. and claim N mentions are live links: clicking a FIG. mention opens the rail to the matching Figures-tab row and briefly highlights it; tapping a rail row (a numeral, a figure, or a claim) scrolls the reading column to the matching paragraph or claim card and, on the bottom-sheet layout, settles the sheet at half height so the row and the destination are both visible at once. A link straight to a specific figure (a shared URL or a bookmark carrying a #fig-Nanchor) opens the Figures tab and scrolls to that figure too, even on a cold, first-ever load of the page. Patents are read and cited, never edited — the viewer is the foundation for claim charts, which capture frozen quotes from it. Paragraph numbers are shown as printed when the source page has them (pre-grant publications, bracketed: [0044]); a granted patent's page carries no official paragraph numbers at all, so those are shown as a plain sequential position instead (¶7, no brackets) — a deliberate, visually distinct form so an ordinal position is never mistaken for an official pincite.

The Numeralstab lists the reference-numeral glossary mined from the applicant's own first introductions (“a surgical fastener 200”): numeral, term, and a link to the first-mention paragraph. It sorts by first mention by default; a “Sort” button toggles to numeric order, and a filter field narrows the list by numeral prefix or term substring as you type. Each row also carries a second, separate control — a small highlight button beside the jump link — that marks every occurrence of that row's numeral in the reading column (see below). The Claimstab lists the same claim set as a jump index — independent claims as roots, each dependent claim nested under the claim it recites, badged the same way as the reading column's claim cards — tapping a row jumps to that claim's card in the reading column rather than duplicating its text in the rail.

Reference numerals in the prose itself are interactive, not just the Numerals-tab rows: hovering one (or tapping it, on touch) opens a small card with the numeral, its term, and where it's first mentioned, plus two actions — jump to that first mention, or highlight every occurrence. Highlighting opens a small navigator bar with a count (“3 of 11”) and / buttons to step between occurrences, scrolling and marking each in turn — the in-app alternative to reaching for your browser's own find (⌘F), and a more precise one: it matches the numeral as a distinct reference, not any digits that happen to appear elsewhere on the page. The same highlight action is also reachable directly from a Numerals-tab row, without first finding the numeral in the text. Only numbers the applicant actually used as reference numerals are interactive this way — a paragraph number (¶200), a figure reference (FIGS. 1-3), a date, or a plain quantity stays inert prose text, since none of those are part of the mined reference-numeral vocabulary; and the card's “first at” reference honors the same official-vs-ordinal paragraph-numbering distinction as the rest of the viewer. The numeral spans in the prose are not themselves separate keyboard tab stops — a reading page can carry hundreds of them — so a keyboard-only visit reaches both actions through the matching Numerals-tab row instead.

The Figurestab renders the drawing sheets for any publication whose manifest lists them, bundled or on-demand alike: the first request for a sheet fetches it from the published source, every later one serves our stored copy; a publication whose manifest has no sheets shows an honest empty state instead of broken images. Sheets are labeled honestly rather than by raw id: the synthetic front-page duplicate USPTO pages emit is called out as “Representative image” and shown small alongside the “Open drawings” button rather than counted as one of the sheets, and the rest are “Sheet N of M.” Clicking any sheet, or “Open drawings,” opens a full-screen detail view with click-to-zoom and ←/→ (or the on-screen arrows) to step through the rest — Escape or a click on the backdrop closes it. Figures nest under the sheet they actually appear on once a publication has been matched: the first time you open a publication's drawings, an automatic pass reads each sheet's printed “FIG.” labels and shows an honest “Matching figures to sheets…” progress line while it works, then swaps in the nested view in place — a sheet's thumbnail followed by the figures found on it, each still linking to the paragraph that describes it. The match is never guessed: a figure whose sheet couldn't be read with confidence stays in a clearly labeled “Not yet matched to a sheet” group instead, and a sheet with nothing matched to it still shows in the gallery on its own. If matching a publication finds no confident matches at all, or the match couldn't run, the tab quietly falls back to the flat figure list and sheet gallery instead of pretending to know a mapping it doesn't have. Once a publication has been matched, that result is stored, so later visits skip the matching pass entirely and go straight to the nested view.

The publication text itself works for any US publication number: it opens at /patents/<publication>; the first open fetches it from the published source and caches it, every later open (from anyone) serves the cached copy. One publication ships bundled and needs no fetch at all (US20190021731A1). /patentslists what's bundled and what's been ingested so far, with a lookup form for anything else. An invalid publication number renders as not-found; a source that can't be fetched, or that fetches but doesn't parse as a patent page, renders a plain error state and caches nothing, so a later attempt tries again. Ingest is bounded: once the corpus holds 1,000 on-demand publications, new fetches are refused until that changes. Select any passage in a paragraph, a claim, or the abstract to capture a frozen citation — a small “Cite” chip appears near the selection. Clicking it opens a small picker: choose one of your claim charts (or type a name and click “New chart” to create one on the spot) and the citation — publication, location, the quoted text, and a capture timestamp — is posted straight onto that chart's first row, creating a stub row automatically if the chart has none yet. The chip then shows “Added to <chart>” with a link into it. “Copy JSON instead” in the same picker still copies the citation to the clipboard, for pasting into the chart table's “Fill from paste” box by hand (see Claim charts below) — the fallback if you'd rather not pick a chart yet, or aren't signed in (an unauthenticated viewer sees a sign-in prompt in the picker instead of a chart list, but can still copy the JSON).

Claim charts (preview)

Reach it from the workbench topbar's “Charts” link, or the same entry in the mobile menu.

/chartslists your existing claim charts (title, last-updated date, linked into their tables) above a create form (a title field, a “Create chart” button) that redirects into /charts/<id>, the chart table itself: one row per claim element, with its evidence citations listed underneath — each showing the frozen quote, the cited publication and locator (a paragraph, claim, or figure reference), and its position. Add a row with the form at the bottom of the table; reorder with the row's / buttons; delete with confirmation. The patent viewer's “Cite” chip is the primary way citations reach a chart now (see Patent viewer above): its picker posts straight onto a chart's first row, or creates a stub row for you first if the chart is empty. Each row's “Add citation” panel here still takes the publication, locator, and quote directly, and still has a “Fill from paste” box that parses a pasted CapturedCitationJSON (the chip's “Copy JSON instead” button) to pre-fill it — the manual bridge from before capture wired in directly, kept as a fallback for pasting from elsewhere or filling in a citation by hand. Every add/reorder/ delete re-fetches the table rather than updating optimistically. Each citation also has a commentary cell — click it to open a rich-text editor (bold/italic/underline via B, I, U, with per-cell undo/redo); blur or Escsaves it and moves the citation back to plain rendering. The “Export .docx” button in the table's toolbar downloads a server-rendered Word document of the chart as it stands — one table, a “Claim element” / “Evidence” header, each row's citations rendered underneath their claim element (quote, publication/locator line, commentary, and the captured figure image when one is attached; a citation whose figure can't be resolved renders a labeled placeholder instead of failing the export). Below the table, a “Versions” section lists saved snapshots (number, optional label, saved date) and a “Save version” button to checkpoint the chart on demand (always a full checkpoint, even if nothing changed since the last one). Exporting also snapshots automatically first — a smaller auto-save version, minted only if the chart's content actually changed since the last stored version — so an exported file always matches a stored version, without a checkpoint per re-export of unchanged content. Each row in that list also has a “Restore” button: confirming it replaces every current row and citation with that version's content immediately — anything not already saved as a version is lost, so save one first if you want to keep it. History itself is never rewritten: the restore is saved as its own new (unlabelled) version at the head of the list — the newest version overall, minted from whatever content the restore just wrote, not necessarily positioned right after the version you picked — and each row's badge (checkpoint, auto-save, or restore) shows how it was made. The page reloads after a successful restore to pick up the rehydrated table.

This is a deliberately minimal first surface: no ProseMirror-editable cells for the claim element or quote text, and no cross-cell (record-level) undo — each commentary cell's undo history resets when you move to another citation. Compare lands in later phase-5.2 work.

02 Reference

Keymap

Structure

TabDemote — push the current article/section deeper into the previous sibling
ShiftTabPromote — lift the current section out of its parent
AltMove the current peer up among its siblings
AltMove the current peer down among its siblings
EnterIn a heading: at end → into body; mid-heading → split into sibling; at start → empty sibling above
Delete the section / article / clause containing the caret. Children go with it. Toast offers Undo.
At the start of an empty hierarchy node (blank heading, no body): delete the node. Toast offers Undo.
At the start of a non-empty heading: first press selects the whole hierarchy node (heading + body + children) with a soft accent ring; second press deletes it. Click or arrow keys exit the selection.
EnterFrom a body paragraph: insert an empty sibling after the current hierarchy node

Formatting

BBold · Ctrl+B on Windows/Linux
IItalic
UUnderline
ShiftDDefine term — wrap the selection as a definition · Ctrl+Shift+D on Windows/Linux
ShiftKMark as usage — wrap the selection as a usage of a registered term · Ctrl+Shift+K on Windows/Linux
ShiftRInsert cross-reference — open the picker for any hierarchy node · Ctrl+Shift+R on Windows/Linux
TabAccept the live cross-reference suggestion when a chip is showing beside the caret. Plain Tab only; Shift-Tab still promotes the current hierarchy node. · Esc dismisses the suggestion silently. With no suggestion active, Tab falls through to the hierarchy demote behavior.
ShiftNext sibling — when caret is on a defined term or term of art, jump to the next occurrence (wraps) · Ctrl+Shift+→ on Windows/Linux
ShiftPrevious sibling — same as ⌘⇧→, in reverse · Ctrl+Shift+← on Windows/Linux

Find and replace

FOpen the find panel · Ctrl+F on Windows/Linux
GNext match
ShiftGPrevious match
EnterNext match (focus inside the find input)
ShiftEnterPrevious match (focus inside the find input)
EscClose the find panel and restore focus to the editor

Outline navigation

Move focus to the previous visible item
Move focus to the next visible item
Expand a collapsed item, or move into its first child
Collapse an expanded item, or move out to its parent
HomeMove focus to the first outline item
EndMove focus to the last visible outline item
EnterNavigate the editor to the focused heading
AZType-ahead — jumps to the next heading whose text starts with what you typed

History

ZUndo
ShiftZRedo
YRedo (alternate)
SSave the current document

Compare mode

AltStep to the previous change (compare mode only) · Option+↑ on Mac. Steps through reviewable changes — added, removed, moved, amended — and clamps at the first change. Ignored while typing in a field.
AltStep to the next change (compare mode only) · Option+↓ on Mac. Steps through reviewable changes — added, removed, moved, amended — and clamps at the last change. Ignored while typing in a field.

Hierarchy vocabulary

The schema enforces exactly five typed levels of legal hierarchy. The same vocabulary is used everywhere — in commands, in issue titles, in the outline rail — so it’s worth learning.

LevelDepthRole
Article1Top-level chapter. Renders centered with an "ARTICLE N" plate.
Section2Numbered subdivision inside an article. Default scheme: "Section 1."
Subsection3Hanging-label block. Used for grouping clauses.
Clause4Operative paragraph with a parenthetical label.
Subclause5Deepest level. Inner enumeration; further nesting is blocked by the schema.

Numbering schemes

Numbering is derived from structure, not typed by the author. Five schemes ship today, switchable from the Numbering choice in the masthead (or the Menu sheet on mobile). Each one models a real drafting convention rather than a variation for its own sake. Clauses and subclauses read (i) / (A) in every scheme — that lettering is close to universal in US practice. Subsections read (a)everywhere except Plain decimal, which carries the full path down one level further.

Default
Plain Arabic numerals. Article 1 Section 1, Section 2. Sections restart their count inside each article, so cross-references name the article first: Article 1, Section 2.
Plain decimal
The multilevel decimal outline — 11.1 1.1.1, then (i) and (A) beneath. No level carries a noun; the number is the whole citation. Standard in technology, services, and commercial agreements.
Bare section
Article 1 heads a run of sections numbered 1.1, 1.2with no “Section” word in the plate. Common in purchase and credit agreements.
Letter article
Lettered top level: AA.1 A.1(a). The convention for exhibits, schedules, statements of work, and policy manuals. Letters follow Word’s sequence, which repeats a single letter rather than counting through combinations: after Z comes AA, BB, CC, and after ZZ comes AAA. The same applies to the lettered subsection and subclause levels in every scheme.
Bylaws
Roman articles over sections that restart in each article: Article IIISection 1, Section 2. The one scheme that cites section-first: cross-references read Section 2 of Article III, which is how bylaws refer to themselves.

Switching schemes does not touch document content. Only the numbering widgets and cross-reference text rerender — the same persisted document opens correctly under any scheme.

An M&A scheme — Roman articles over zero-padded sections, Article ISection 1.01 — shipped previously and has been withdrawn. It was the only scheme whose Word export depended on features that Word, Google Docs, Pages, and LibreOffice each handle differently, so a document exported under it did not read the same in every one of them. Documents saved under it open as Bare section — the same Article 1 heading over a dotted section path — and export that way too, whether or not you have opened them. The conversion is applied every time the document is read; it is written back to the stored document the next time you save. Nothing in the document body changes either way.

Version reasons

Every version carries a reason that explains how it was minted. Three reasons exist today:

checkin
A labelled major version minted when the holder chooses Check in. Check-ins are the N.0 rows —1.0, 2.0, and so on. The Major filter in the History drawer keeps only these rows.
save
A minor version minted on every S while checked out. These are the N.M rows with M > 0 — e.g. 2.1, 2.2. Visible in the All filter only.
restore
A minor version minted when you restore a past version. The body comes from the chosen snapshot; the version number continues from where the document is today — history is never rewritten. Restore requires holding the checkout.

The editor recognizes terms from a built-in Legal Terms of Art dictionary — covering both M&A and Master Services Agreement vocabulary — and stains the glyphs themselves with a per-tier accent (no underline): oxblood for hard (statutory) terms, dark mustard for semi-rigid, dark purple for negotiated, dark moss for drafting conventions. When the cursor lands in or beside a recognized term, the same hue brightens a notch so the active match pops without swapping identity. The Legal-rail legend dots and tier labels mirror the resting accent so the rail key is the literal color you see in prose.

The Lens toggle in the topbar controls how much recognition shows through: Off hides all decorations, Dim shows only Hard (statutory) terms and fades the surrounding prose to 80% alpha so defined-term marks and Terms of Art read as the only substance on the page, and On shows all four tiers at full ink. The choice persists per-browser; default is On.

Your personal term library (see “Your term library” above) recognizes terms through this same system — it isn’t a second, separate highlighting pass. A library entry is only ever tier negotiated or convention, so it stains prose in dark purple or dark moss just like a built-in term of art at that tier. When a term exists in both your library and the built-in baseline, the library entry is the one the editor matches; the baseline entry rides along as the shadowed secondary row in the Term Inspector card below.

Term Inspector

Place the caret inside a recognized term (a click or a single tap) and a small card surfaces below it naming which layer is answering — Defined in this document, Your library, or Terms of art(see “Your term library” above for the precedence order) — followed by the term name, tier, and plain-language definition. A promoted library entry also carries a provenance line naming the document it was saved from. The card shows a watch note when one applies, and — if the term is also defined locally via ShiftD — a Jump to definition in document link. When a lower-precedence layer also has an entry for the same term, an Also in …row at the bottom expands to show it without hiding which layer actually answered. The card’s left stripe carries the tier hue; the rest of the card stays ink-on-paper so the page never reads as a Christmas tree.

The card stays open while the caret sits inside the term and closes when the caret moves out. Alt-click (or double-tap) on a term shows the card without moving the caret — useful when you want to read the entry while working elsewhere. Dismiss the card early with Esc, the × button, by clicking outside, or — on a touch device — by grabbing the handle at the top of the card and flicking it sideways; it stays closed until the caret leaves the term and returns. The same swipe gesture dismisses the cross-reference inspector.

Known gaps in Phase 1

  • Defined-term marks ship with a wrap command, a rename command, the Defs rail tab, and phantom detection. Per-doc phantom dismissal, auto-suggest for usages, and the section-gutter coordination still need to land.
  • No cross-reference marks yet (Phase 2).
  • No axe-core CI gate yet. A11y is verified manually plus a vitest unit test on the heading-level decorations; full pipeline integration is tracked separately.
  • No real-time collaboration (Phase 3).
  • Tables, images, and footnotes are not preserved when pasted.
  • The Redline lens shows changes since checkout and lets you accept or reject them at the word, clause, or whole-document level; an unresolved redline now survives saves and reloads while you stay checked out.