@marketrix.ai/design
v0.4.3
Published
The Marketrix design system: React components, the Tailwind v4 theme, tokens, chart colours, Inter and the logo.
Readme
@marketrix.ai/design
The Marketrix design system: React components, the Tailwind v4 theme, the one light and dark palette, class tokens, the chart palette, the Starlight theme, Inter as woff2 and the logo. Its consumers are app, personaos, monitor, infra's auth and mail, meet, docs and api; widget and website deliberately stay independent.
Use
Pin an exact version (bun add --exact @marketrix.ai/design), never a range. react and react-dom 19 are peers.
@import "@marketrix.ai/design/theme.css";
@import "./design-sources.css";The theme brings in Tailwind, the palette, the fonts and the one base layer (page ground, cursor, scrollbars,
reduced motion). design-sources.css is written by design-sources src/styles/design-sources.css from the app's root
and committed. The theme detects no sources, so it names them all: the app's top-level code directories and only the
components the app imports (and what they import), so the app's CSS carries only their classes. Rerun it after
changing which components you import or adding a code directory; design-sources <path> --check in ci fails while
it is stale. Docs' Starlight takes
@marketrix.ai/design/starlight.css as its one customCss. Both build on the internal brand.css.
Components are one subpath each, with no barrel: import Button from '@marketrix.ai/design/Button'. Class tokens come
from /tokens (Tone, TONE_TINT, SEMANTIC_TONE, INK, INVERSE, SURFACE, SELECTABLE, ICON_SIZE, LINK, SPINE,
Z, …); a hand-built element
reaches for one of these rather than re-typing its classes. A single choice among short options is SegmentedControl;
among described options, RadioGroup. The chart palette comes from /chart: CHART_VARS for chrome a browser draws
(it turns dark) and CHART_TICK for every axis tick and in-chart label, CHART_CHROME and the fills in hex for PDFs and chart data, SENTIMENT_TONE and SENTIMENT_FILL for
one sentiment scheme, DIVERGENCE_TONE and DIVERGENCE_FILL for consensus, segmentFill for identity series and
HEATMAP_SEQUENTIAL with rampColor for heat. The static hex THEME (gray ramp, ink roles, tone hues, success green, font stack)
for email and PDF comes from /hex, with assets/mark.png and the fonts/*.ttf a PDF embeds. A host wires its seams
once:
LinkContext(/Link) takes its router's link, such asnext/link; without it links are plain<a>.ToastProvidertakesdescribeError(error, fallback)(wording,missing,warning, anactionlink) andlogError;ReadGatewords failures through the samedescribeError.PaidPlanContext(/paidPlan),TakeoverHostContext(/FullscreenTakeover) andErrorBoundary'sonError.
Modal, ConfirmDialog, Drawer and FullscreenTakeover are native modal <dialog>s and Menu, Popover and
Tooltip panels native popovers, all rendered where they are written rather than portalled to <body>: the browser's
top layer stacks them, so keep one out of an ancestor that is display: none or inert. A panel opened from a dialog
is inside it, and the toast stack moves into the topmost open dialog. A test DOM has neither, so a consumer's harness
calls installOverlayStandIns() from @marketrix.ai/design/overlayStandIns once after installing its DOM.
The page frame is AppShell with PageHeader beside a NavFrame; a page without the rail is a CenteredPanel.
The favicon is assets/favicon.png: a Next site renders <Favicon /> (/Favicon) in its document head and lists
@marketrix.ai/design in transpilePackages, so its bundler emits the image; docs, on Astro, copies it into public/.
Theme
Every colour is a light-dark() pair, so classes written for light turn dark with no dark: variant. data-theme on
<html> is the one switch: unset or light, dark, or system to follow the OS. data-theme='light' on any other
element pins that subtree light (FullscreenTakeover and CenteredPanel's band use it). ThemeToggle writes it, and
NavFrame and CenteredPanel render it, so a host places none. A host sets data-theme="system" and renders
<ThemeScript /> (/ThemeScript) in its document head, or inlines THEME_SCRIPT in a static page, so a remembered
choice applies before the first paint; a host whose CSP refuses inline scripts adds THEME_SCRIPT_HASH to
script-src.
Develop and release
bun run check, bun run test and bun run build from design/; infra's bun run ci runs all three. To try a change
in a consumer, bun pm pack and depend on the tarball by file:. Bump version, merge, then tag main with
design-v<version>; .github/workflows/publish-design.yml publishes it.
Inter is licensed under the SIL Open Font License (fonts/OFL.txt); everything else under Apache-2.0 (LICENSE).
