DTA Drafting Table
DTA Drafting Table is the design system of this website, the dta diff reports and the playground. It looks like a drafting table: warm paper, blueprint blue, ink outlines and orange redlines that measure what changed. Its dark mode, Graphite, is the dark side of the same paper. Since the landing redesign the paper is one plain surface with a gravity well drawn on it: everything on the page gravitates towards the token.
It is also a demo of DTA itself: the tokens are DTA token files in site/tokens, linted with dta lint and built with dta build into the CSS this page uses. The token pages read the same files through @dta/core.
Principles
Section titled “Principles”- Measure, don’t decorate. The signature element is the redline: a
stroke-redlineline insignal-bgwith a mono label naming the token it measures (radius.lg · 18). It points at real values, never at nothing. - Two inks and a signal.
fg-defaultandaction-bgcarry the page.signal-bgappears only where something changed or is moving through the workflow. More than three orange marks on a screen is too many. Results have their own status colours (success, warning, error), always with a marker shape and a word;signalnever means an error or a warning. - Borders, not shadows. Surfaces get a
stroke-hairlineinborder-default; interactive elements astroke-inkinborder-strong. Borders are complete or straight: a box with rounded corners has its outline on every side; a rule on one side (a row’s hairline, a section’s top rule) belongs to a box with square corners. Never a border that stops on a rounded corner (it tapers off around the curve), never a faded one (no gradient or masked borders).components.test.tschecks this for the components, the page styles, the docs components and thedta diffreport. - One surface. The page is plain paper (
bg-canvas), without grid lines. Grid paper (bg-gridat aspace-4pitch onbg-subtle) appears only where something is literally being inspected: the redline stage and the card’s stage variant. Never as a page, panel or section background (a test checks the components). - The well is decoration. The gravity well of the landing page (a polar mesh swirling into a hole, with cubes, spheres and dust in orbit) labels nothing and tells no story; the copy does. It is drawn from the
well-*tokens, fades into the plain surface before any content starts, and stands still underprefers-reduced-motion. - AAA. Text reaches 7:1 on its ground in both themes (4.5:1 for large text, 24 px or 18.66 px bold), measured over the effective background; edges and the signal line reach 3:1. The one exception is the redline label (
signal-fgonsignal-bg, 5.7:1): no orange can be a 3:1 line on paper and carry 7:1 text at once. A test checks the token pairs; a browser test checks the rendered pages. - Motion against change blindness. Every change a person should notice is transitioned, never instant: what appears comes from where it comes from and goes back there, content that changes in place crossfades, a changed value is briefly highlighted in
action-subtle, and layout moves instead of jumping. Short and functional, on the motion tokens (no bounce, no decoration beyond the well). Underprefers-reduced-motionnothing moves and changes are instant, but changed values are still highlighted: that is information, not motion. The rule, with do and don’t: Motion.
Plain, specific, calm. Short sentences. Name the thing: “1 rename: color.cta → color.action”, not “Some changes were detected”. Commands are shown as command chips you can copy ($ npm create dta with a copy icon that turns into a tick), the same component everywhere; the chip, not a blue button, is the call to action. Designers and engineers are addressed equally; never “simply” or “just”.
Patterns
Section titled “Patterns”- Severity markers. Severity is a word plus a marker shape, coloured with the status colours: an error is a filled square in
status-error-marker, a warning an open ring instatus-warning-marker, a clean result the pass dot instatus-success-marker, each with its word instatus-*-text. The shape and the word carry the meaning; the colour adds to them, never alone.signalis never used for errors or warnings (it means “changed”). The Findings list and its rule rows, the Checks, Chips, the Summary line counts, a finding’s kicker in the Detail panel and the rows of the Graph canvas use it; a selected line keeps its marker and word in their status colours on the selection tint. - Examples stay blue and grey. Example content (sample tokens, example UI in stories, the fixtures in the playground and the docs, a report’s example data) uses blues and neutral greys, never the system colours (
signal, success, warning, error) or a hue near them, so an example never reads as a change or a result. The Badge for example data is a neutral outline. The rule and its test: Status colours. - Paths break between segments. Token paths, alias ids and file paths wrap after a
/or.and keep every segment whole, through one helper (Token path); only a single segment wider than its box breaks inside, as a last resort. - Status banner. What stops the work (input that cannot be read, a build with errors) is a banner: the status’s subtle tint inside a complete 2 px outline in its marker colour, every line in its status text (Findings with
banner). Not for a lint view or a hint. - A workspace, not a stacked page. A tool that needs input first gives the page to the input (Token input); once something is loaded the input collapses into a Source bar (a View Transition), a Summary line stays visible, and the views are Tabs (sticky on phones, the selected one in the URL hash). Summaries first: lists show counts and open to their lines.
- Side panel / bottom sheet. Details of a selected row open in the Detail panel so the view behind stays in place: beside the view from 1024 px (non-modal, sticky), as a bottom sheet below (a modal native
<dialog>, the page veiled with the canvas). Focus moves to the panel and returns to the row that opened it; Escape closes it. A finding’s panel steps on with “Next finding” without closing; “Show in graph” and “Show in lint” lead from a finding to its token on the graph and back, and the hash keeps where you are. The panel comes in from the right, the sheet slides up from the bottom, and both go back the way they came. No modal dialogs for the views themselves. - A graph you can read on any screen. Dependencies are drawn as layer columns with an arrow from each alias to the token it uses (Graph canvas): rows as ink outlines, findings in the status colours with shape and word, the selection and its chain in the blueprint action colours. The arrow keys walk along it. On phones the same data is a list of layers and chains (Graph list); the Graph switcher chooses the brand and breakpoint (segments on desktop, native selects on phones).
- Files to take away. Generated files are listed, not dumped: Output options above them choose what is built, Output files group them by kind with one download per group and Copy and Download per file, a file’s text opens in the Detail panel, and one primary “Download all” gives everything in the folders the CLI writes. Copy is the Copy button, Download a quiet Button next to it. Downloads are made in the browser (nothing is uploaded), and the way back to the CLI is the CLI hand-off: the generated config and the commands as command chips.
In this section
Section titled “In this section”- Tokens: colours, typography, spacing, radius and stroke, motion
- Rules: Motion (transitions against change blindness, reduced motion), Status colours (success, warning, error: shape, word and colour)
- Components: Button, Command button, Chip, Badge, Card, Text field, Terminal, Redline, Diff card (a story row of the
dta diffreport); the site frame: Logo, Nav, Theme switch - For the landing page: Workflow rail, Scene, Example button, Token rows, Token cycle, Checks, Facts, Gravity well, Floating objects
- For the playground (Preact components, rendered by its island; the stories render them to static HTML): Token input, Source bar, Summary line, Tabs, Structure table, Findings, Graph switcher, Graph canvas and Graph list (the dependency graph; its layout in
graph-layout.ts), Detail panel, Output options, Output files, Copy button, CLI hand-off, Token path (paths that break between segments), Changed (a value that lights up when it changes). Their buttons are the Button through the sharedButton.css, their commands the Command button throughCommandButton.css. - Every component example also exists as an isolated story for visual testing, at desktop and phone width where the layout changes; the list is
/stories/manifest.json.