01
Prose Long reading gets the reading role at a 66-character measure. The page, not the chrome, is the product.
Anatomy
.preceda-proseNewsreader 17/1.55, ink, max 66ch. Apply to the container of paragraphs. Variants Reading
Paper
Our endeavour in this judgment is to ensure that police officers do not arrest the accused unnecessarily and Magistrate do not authorise detention casually and mechanically.
Lamp
Our endeavour in this judgment is to ensure that police officers do not arrest the accused unnecessarily and Magistrate do not authorise detention casually and mechanically.
At 390 px The measure is a maximum; at 390 px prose fills the column with the page gutter.
390 px
Our endeavour in this judgment is to ensure that police officers do not arrest the accused unnecessarily and Magistrate do not authorise detention casually and mechanically.
Accessibility Keep 17px and 1.55 leading for anything read at length. Text resizes with the user’s root font size; the measure is in ch. Do Use for judgments, letters and the case page. Use the body role (15/1.55) for the desk draft. Don’t Set long text in Inter. Widen the measure past 66ch to fill a wide screen. Usage HTML <div class="preceda-prose"><p>…</p></div>React <div className="preceda-prose">{paragraphs}</div>02
Running head & label Short chrome that orients: the forum above a sheet, a field’s name. Never a paragraph.
Anatomy
.preceda-running-headInter 12, 600, tracked uppercase, secondary ink. Above a sheet or section.
.preceda-labelThe same face for a form label; pair with htmlFor.
.preceda-type-labelThe 0.2 serif small-caps label role, as in the approved screenshots. Variants 0.2 label role
The form the workspace, case and authorities screens use.
Paper
In the Court of Sessions, Saket
Lamp
In the Court of Sessions, Saket
At 390 px Running heads truncate before they wrap; keep them to one line at 390 px.
Accessibility Uppercase is CSS only; the source text stays in sentence case for screen readers. Secondary ink passes 4.5:1 on every surface. Do Keep to a few words. Use a real <label> for fields. Don’t Use tracked caps for sentences or buttons. Usage HTML <p class="preceda-running-head">Draft instrument</p>
<label class="preceda-label" for="objective">Objective</label>React <p className="preceda-running-head">Draft instrument</p>03
Citation A citation is an exact character sequence. Mono with tabular figures makes it checkable at a glance.
Anatomy
.preceda-citationJetBrains Mono 13, tabular figures. Inline in serif text. Variants Inline
Paper
Arnesh Kumar v. State of Bihar, (2014) 8 SCC 273
Lamp
Arnesh Kumar v. State of Bihar, (2014) 8 SCC 273
Neutral citation
Paper
2014 INSC 463 · Crl. A. No. 1277 of 2014
Lamp
2014 INSC 463 · Crl. A. No. 1277 of 2014
At 390 px Citations do not break inside a reporter reference; allow the line to wrap before it.
Accessibility Screen readers read the characters as written; do not substitute symbols for words. Do Pair with a verification status mark. Keep party names in the serif; only the reference is mono. Don’t Set case names in mono. Link a citation without saying where it goes. Usage HTML <span class="preceda-citation">(2014) 8 SCC 273</span>React <span className="preceda-citation">{citation}</span>04
Rule A printed rule groups the record. Prefer a rule and whitespace to a box.
Anatomy
.preceda-ruleA 1px <hr> in the rule colour. Accessibility An <hr> is a thematic break; use a CSS border for purely visual separation. Do Use hairline or rule; ink rules only under a running head. Don’t Nest bordered containers to separate content. Usage HTML <hr class="preceda-rule" />React <hr className="preceda-rule" />05
Sheet A sheet is a page lying on the desk: raised paper, a rule, the lightest shadow.
Anatomy
.preceda-sheetRaised surface, rule border, small radius, sheet shadow. Padding is the consumer’s. Variants Sheet
Paper
Draft · 10:53
1. The Applicant is the brother-in-law of the complainant.
Lamp
Draft · 10:53
1. The Applicant is the brother-in-law of the complainant.
At 390 px At 390 px a sheet runs to the gutters; the numbered document sheet (T5) sets its own margins.
Accessibility Use a landmark or article element when the sheet is a document. The shadow is not a boundary; the rule is. Do Hold one document per sheet. Don’t Stack sheets inside sheets. Use a sheet as a card for list items. Usage HTML <article class="preceda-sheet">…</article>React <article className="preceda-sheet">{children}</article>07
Link Links go somewhere. Binding ink on a quiet printed underline that darkens on hover.
Anatomy
.preceda-linkInter 14/600, binding ink, rule-strong underline at 0.25em offset. Accessibility Underlined, so it does not rely on colour. Link text names the destination. Do Use for navigation and references. Don’t Use for actions that change state; use a button. Usage HTML <a class="preceda-link" href="/case/…">Read authority</a>React <a className="preceda-link" href={href}>Read authority</a>08
Field A field is a ruled line with a name above it and its error below it. Nothing decorative.
Anatomy
.preceda-fieldRaised surface, rule-strong border, inherits the font.
[aria-invalid="true"]Border turns to the error colour.
.preceda-field-errorThe associated message, Inter 13 in error ink. At 390 px Fields fill the column at 390 px; inputs stay at 16px effective size or larger to avoid zoom.
Accessibility Every field has a <label>; placeholder is a hint, never the label. Link the error with aria-describedby and set aria-invalid. Do Label above the field with .preceda-label. Don’t Put the only instruction in the placeholder. Usage HTML <label class="preceda-label" for="court">Court and jurisdiction</label>
<input class="preceda-field" id="court" aria-invalid="true" aria-describedby="court-error" />
<p class="preceda-field-error" id="court-error">Court and jurisdiction are required.</p>React <input className="preceda-field" id="court" aria-invalid={Boolean(error)} aria-describedby="court-error" />09
Tabs Tabs orient within one surface. The selected tab is underlined in binding; the rest recede.
Anatomy
.preceda-tabsThe ruled tab row (role="tablist").
.preceda-tabOne tab; [aria-selected="true"] draws the binding underline.
<TabList>React: roving focus with arrows, Home and End. Selection stays with the consumer. Variants Desk tabs
Interactive after hydration: click or use the arrow keys.
Paper
Draft Authorities Facts Chronology
Lamp
Draft Authorities Facts Chronology
State matrix State Paper Lamp
default Draft Authorities Facts Chronology
Draft Authorities Facts Chronology
hover Draft Authorities Facts Chronology
Draft Authorities Facts Chronology
focus-visible Draft Authorities Facts Chronology
Draft Authorities Facts Chronology
At 390 px At 390 px the row scrolls horizontally; it never wraps to two lines. Swipe arrives with T3 Tabs.
Accessibility WAI-ARIA tab pattern: one tab stop, arrows move, Home/End jump. Each tab controls a panel via aria-controls. Do Keep to four or five short nouns. Don’t Use tabs for site navigation. Usage HTML <div class="preceda-tabs" role="tablist" aria-label="Desk">
<button class="preceda-tab" role="tab" aria-selected="true">Draft</button>
<button class="preceda-tab" role="tab" aria-selected="false" tabindex="-1">Authorities</button>
</div>React import { TabList } from '@luvkapur/preceda-design-system/react';
<TabList aria-label="Desk">
<button className="preceda-tab" role="tab" aria-selected>Draft</button>
</TabList>10
Focus Keyboard focus is always visible and always opaque: a 2px focus ring, offset 2px.
Anatomy
:focus-visibleShared by button, link, field, tab and dialog. Accessibility The focus colour reaches 3:1 on every adjacent surface in both themes. Never remove outline without an equal replacement. Do Import focus.css with any per-component CSS file. Don’t Style focus with a tint or shadow alone. Usage HTML @import '@luvkapur/preceda-design-system/css/focus.css';React // Focus is CSS-only; no component is required.11
Dialog shell A dialog asks one bounded question, with enough context to answer and a way back to the draft.
Anatomy
.preceda-dialogNative <dialog>: raised sheet, rule-strong border, dialog shadow, dimmed backdrop.
.preceda-dialog__sheetPadding container.
.preceda-dialog__titleSerif 30; labels the dialog.
.preceda-dialog__descriptionSecondary ink; describes the dialog.
<DialogShell>React: wires aria-labelledby/-describedby. Opening policy stays with the consumer. Variants Question
Shown inline here; in product it opens with showModal().
Paper
Which court passed the impugned order? This completes the jurisdiction paragraph.
Return to draft Submit answer
Lamp
Which court passed the impugned order? This completes the jurisdiction paragraph.
Return to draft Submit answer
At 390 px At 390 px the dialog is the viewport width less 2rem; actions stack. The bottom Sheet arrives in T4.
Accessibility showModal() gives focus trapping and Escape for free. Title and description are wired automatically by DialogShell. Return focus to the invoking control on close. Do Ask one question. Offer “Return to draft”. Don’t Use a dialog for a notification; use a toast (T4). Usage HTML <dialog class="preceda-dialog" aria-labelledby="q">
<div class="preceda-dialog__sheet">
<h2 class="preceda-dialog__title" id="q">Which court passed the impugned order?</h2>
<div class="preceda-dialog__body">…</div>
</div>
</dialog>React import { DialogShell } from '@luvkapur/preceda-design-system/react';
<DialogShell ref={ref} title="Which court passed the impugned order?" description="…">
{answer}
</DialogShell>