## OPERATOR design system

This project builds its interface with OPERATOR (`@operator-ds/react`). Use its components, and look them up instead of guessing: these commands print the facts for the version installed here. Run them with the project's package runner (`npx operator-ds …`, `pnpm exec operator-ds …`).

- `operator-ds search <need>`: which component or recipe answers a need
- `operator-ds component <Name>`: one component's options, nesting rules and example (`--dense` for the short form)
- `operator-ds add <recipe>`: copy a working screen into the project to adapt
- `operator-ds check <paths>`: check written code against the contract

### Rules

1. Look a component up before using it (`operator-ds component <Name>`). A prop or value that is not in its contract does not exist; do not guess from other libraries.
   Wrong: `<Button isLoading leftIcon={<Spinner />} color="green">Save</Button>`
   Right: `<Button disabled={saving}>Save</Button>`
2. Use an OPERATOR component before writing markup. A native button, input, select, table or dialog, or a styled div standing in for one, is an escape hatch: search first (`operator-ds search <need>`).
   Wrong: `<button className="border px-3u">Deploy</button>`
   Right: `<Button>Deploy</Button>`
3. For a whole screen, start from a recipe and adapt it (`operator-ds search <need>`, then `operator-ds add <recipe>`). Composing a screen from nothing is the last resort.
4. One primary Button in view at a time. It is the only button with a cut corner at rest, so two of them say there are two main actions. Use secondary or tertiary for the rest.
   Wrong: `<Button>Save</Button> <Button>Export</Button> <Button>Share</Button>`
   Right: `<Button>Save</Button> <Button variant="secondary">Export</Button> <Button variant="tertiary">Share</Button>`
5. When the option you want is missing, the answer is another component, not a new value. A green button is not a Button variant: status is a Badge.
   Wrong: `<Button variant="success">Online</Button>`
   Right: `<Badge variant="success">Online</Badge>`
6. Status is never color alone. Say it in words with a Badge or an Alert.
   Wrong: `<span className="text-oprt-error">●</span>`
   Right: `<Badge variant="error">Link lost</Badge>`
7. Wrap every form control in a Field. The Field wires the label, help text and error to the control; do not set id or aria attributes for that yourself.
   Wrong: `<label htmlFor="callsign">Call sign</label> <Input id="callsign" />`
   Right: `<Field label="Call sign"><Input /></Field>`
8. A part goes inside its parent, and only what a parent allows goes inside it: CardHeader in Card, TabsTrigger in TabsList, SelectOption in Select. Nothing you can click goes inside a Button or a Badge.
9. Color, spacing and type come from OPERATOR tokens. No hex or rgb colors, no arbitrary pixel values, and no rounded corners: the radius is 0 everywhere.
   Wrong: `className="bg-[#1a1a1a] p-[13px] rounded-md"`
   Right: `className="bg-oprt-surface-1 p-2u"`
10. Write labels in normal case. Buttons, tabs, badges and headings uppercase themselves; names, IDs, values and body text keep the case you give them. Never uppercase a string in code.
   Wrong: `<Button>{label.toUpperCase()}</Button>`
   Right: `<Button>Deploy</Button>`
11. There is one theme and it is dark. Do not add a light theme, a theme switch, or dark: variants.
12. Unknown, stale and unavailable are states to show, never values to fill in. Keep the UTC label on a time, and keep data quality separate from the condition of the thing measured.
13. Pass data and settings as props. Sorting, focus, keyboard handling and announcements belong to the component; do not rebuild them around it.
14. Before you call the work done, run `operator-ds check <paths>` and fix what it reports.

### Components

- ActionStatus: show the outcome of an action the user just took, with a way to retry
- Alert: an inline message that needs attention: error, warning, info or success; a callout
- AppShell: the frame of an app or workspace: its name, mode, data connection and UTC time; hold the app's Sidebar, as its navigation
- AttachmentPreview: show an attached file: its name, type, size and a safe preview
- Avatar: show a person or unit by initials
- Badge: show a status label; a category or count that is read, not clicked
- Breadcrumb: show where a page sits in the hierarchy
- BulkActionBar: act on several selected rows at once
- BulkResults: show what happened to each item after a bulk action
- Button: trigger an action; submit a form
- ButtonGroup: a row of related buttons; a segmented set of actions
- Calendar: pick a day from a month grid that is always visible
- Card (CardHeader, CardBody, CardFooter): group related content in a bordered panel
- Chart: plot data as a line, area, bar, scatter, histogram or heatmap
- Checkbox: a yes or no choice in a form; select rows; a parent whose children are partly selected
- Collapsible (CollapsibleItem): sections that expand and collapse (an accordion)
- CollectionState: the empty, loading, error or no-results state of a list or table
- ComboBox: pick one from a long or searchable list; autocomplete with results fetched as you type
- CommandPalette: a keyboard command launcher: search and run an action
- ConfirmDialog: confirm a destructive or high-consequence action
- ContextMenu: right-click actions on an item, with a visible menu button as well
- CoordinateInput: enter a latitude and longitude
- CopyButton: copy an exact value (an ID, a coordinate, a command) to the clipboard
- DataGrid: a large or interactive table: selection, sorting, column sizing, paging, thousands of rows
- DataTable: a simple table of rows, with optional sorting
- DatePicker: pick one date
- DateRangePicker: pick a start and an end date
- DateTimePicker: pick a date and a time in a named time zone
- DescriptionList: label and value facts about one thing; metadata or measurements
- Dialog: a modal for a focused task or form
- Divider: separate content with a rule, with an optional label
- DropdownMenu (DropdownMenuItem, DropdownMenuSeparator, DropdownMenuLabel): a menu of actions opened from a button
- EntityPreview: summarize one record: its identity, condition, key facts and report quality
- EventTimeline: events and durations on a time axis, in lanes
- Field: give a form control its label, help text and error
- FileUpload: choose, drop or paste files
- FilterBar: quick toggle filters above a list or table
- FormErrorSummary: list a form's errors at the top, each leading to its field
- FormSection: group related form fields under a heading
- InlineEdit: edit one value in place, with save and cancel
- Input: a single line of text; a search box
- Inspector: a side panel of details that leaves the page usable
- JobStatus: the state and progress of a long-running job, with cancel and retry
- LayerControl: turn map layers on and off, and set their opacity and order
- Link: go to another page or place
- MapControls: zoom and reset-north buttons for a map
- MapLegend: explain a map's symbols
- MapScale: a distance scale bar for a map
- MediaFrame: show a camera image or video frame with its freshness and capture time
- MultiSelect: choose several options from a short list
- NumberInput: enter a number with a unit, a range and steps
- OperationalStatus: show the data quality, source and last update time of a reading
- PlaybackControls: play, pause and scrub through recorded time
- Popover: details or controls in a small panel anchored to a button
- Progress: show how far along a task is, or that it is working
- PropertyFilter: build a filter from property, operator and value clauses
- RadioGroup (Radio): choose exactly one of a few visible options
- Select (SelectOption): choose one option from a dropdown
- Sidebar (SidebarLogo, SidebarSection, SidebarItem, SidebarFooter): app navigation in a vertical rail
- Skeleton: a placeholder in the shape of the content while it loads
- Slider: pick a value or a range along a track
- Sparkline: a tiny trend line inside a row or card
- SplitPane: two resizable panels, side by side or stacked
- StatCard: one headline metric with its trend
- Tabs (TabsList, TabsTrigger, TabsContent): switch between views of the same subject
- TagGroup: a set of tags, which can be removable
- Textarea: several lines of text
- TimeField: enter a time of day on the 24-hour clock
- TimeRange: pick a UTC time window, with presets
- Toast: a brief notification that something happened
- ToastProvider: the host for Toast notifications, once at the root of the app
- Toggle: switch a setting on or off, taking effect at once
- Toolbar (ToolbarSeparator): a bar of actions for a view or a selection
- Tooltip: a short hint on hover or keyboard focus
- TreeView: browse a hierarchy: folders, units, asset trees
- UploadQueue: show files as they upload, with progress and recovery

### Recipes (whole screens to start from)

- CommunicationsConsole: Coordinate fictional military support channels, compose messages, distinguish delivery from acknowledgment and retain drafts through connection changes. `operator-ds add communications-console`
- FacilityMonitoring: Review supplied cameras, equipment, map and events at one shared time, with explicit recording gaps, session bookmarks, decoded-frame snapshots and camera-request outcomes. `operator-ds add facility-monitoring`
- OperationsMap: Inspect military base-support reports on a linked map and table, with explicit source freshness, retained positions, uncertainty, measurement and accepted annotations. `operator-ds add operations-map`
- AssetManagement: Manage an industrial equipment register, inspect condition and ownership, create records and revise service assignments with explicit save outcomes. `operator-ds add asset-management`
- IncidentResponse: Triage military support incidents, assign case ownership, review evidence, resolve cases and prepare a shift handover. `operator-ds add incident-response`
- MaintenancePlanning: Schedule industrial maintenance in crew and resource lanes, review prerequisites and resolve time and availability conflicts before applying changes. `operator-ds add maintenance-planning`
