Barton Design System

Install & Usage

How a consuming Barton project attaches this library, imports its primitives, applies a domain skin, and stays inside the CTB and source rules.

Draft
You are hereInstall & Usage30kBranchDraftsource: this repository — src/design-system/bartonnext: release from Project Settings

1 · Attach the library

manual · project settings

  1. Step 1 — release

    On this library project, use Publish design system (top-right). That regenerates .lovable/design-system.json and the rules files, and bumps the version.

  2. Step 2a — new project

    When creating the project, choose Use a design system and pick the released Barton Design System.

  3. Step 2b — existing project

    Go to Project settings → General → Design system and attach it. Managed components then live under src/design-system/<slug>/.

Release and attach are not code actions

Blocked

Publishing this library and attaching it to another project happen in Lovable Project Settings. Nothing in this repository can perform them, so this page documents the steps rather than automating them.

opens from: Dave · Project Settings

2 · Import pattern

single entry point

Everything is re-exported from @/design-system/barton. Import from the barrel so a consuming app never depends on internal file layout.

components + types

// One entry point. Never deep-import individual files.
import {
  FractalShell,
  BlockIdProvider,
  AdminBlockIdToggle,
  ScopeBreadcrumb,
  OrientationStrip,
  HubCard,
  SpokeCard,
  StatPanel,
  StatusBadge,
  AltitudePill,
  EvidenceBadge,
  SourceList,
  EmptyState,
  BlockedState,
  DataTable,
  VerificationChecklist,
  CTBMiniMap,
  DataFlowMap,
} from "@/design-system/barton";

// Types travel with the primitives.
import type {
  Altitude,
  BartonState,
  CTBNode,
  DomainSkin,
  EdgeKind,
  RailNavGroup,
} from "@/design-system/barton";

tokens must load first

/* src/styles.css — import once, at the app entry. */
@import "tailwindcss" source(none);
/* Token source of truth travels with the library. */
@import "./design-system/barton/theme.css";
@source "../src";

/* Tokens must load before any primitive renders: every component
   references semantic tokens (bg-surface, border-line, text-verified,
   px-d3, py-row-default). Without them the components render unstyled. */

3 · App shell recipe

copy verbatim

FractalShell is content-neutral: nav, skin and copy are configuration. Wrap it in BlockIdProvider so the admin overlay works, and always render <Outlet /> inside it.

src/routes/__root.tsx

// src/routes/__root.tsx — app shell for a new Barton cockpit.
import { Outlet } from "@tanstack/react-router";
import {
  AdminBlockIdToggle,
  BlockIdProvider,
  FractalShell,
  type DomainSkin,
  type RailNavGroup,
} from "@/design-system/barton";

// Nav mirrors the active CTB. Groups are branches; items are leaves.
const NAV: RailNavGroup[] = [
  {
    label: "Intake",
    items: [
      { label: "Queue", to: "/queue", hint: "unworked records" },
      { label: "Exceptions", to: "/exceptions", hint: "repair", state: "repair" },
    ],
  },
];

function RootComponent() {
  const [skin, setSkin] = useState<DomainSkin>("core");

  return (
    <BlockIdProvider>
      <FractalShell
        productName="Mission Control"
        productMeta="read surface · adapter-backed"
        nav={NAV}
        skin={skin}
        onSkinChange={setSkin}
        headerRight={<AdminBlockIdToggle />}
      >
        {/* Required: nested routes render here. */}
        <Outlet />
      </FractalShell>
    </BlockIdProvider>
  );
}

4 · Page recipe

orientation → sections

Breadcrumb, then orientation strip, then content sections. A page that cannot say its scope, altitude, state and source mode is not finished.

page body

// Every page: where am I, what state is it, what is the source.
<ScopeBreadcrumb
  path={[
    { label: "Mission Control", to: "/", altitude: "50k" },
    { label: "Intake", to: "/queue", altitude: "30k" },
    { label: "Record 4471", altitude: "10k" },
  ]}
/>

<OrientationStrip
  scope="Record 4471"
  altitude="10k"
  state="draft"          // from a real check — never hardcoded green
  sourceMode="read-only adapter"
  nextAction="verify payer mapping"
/>

<DataTable
  columns={columns}
  rows={rows}
  rowKey={(r) => r.id}
  density="compact"
  caption="source: intake adapter · read-only"   // provenance is required
  emptyTitle="No records in queue"
/>

5 · Domain skins

accent only

A skin retints accent and rail. It never changes structure, density, radii or the meaning of a state color — a blocked badge looks blocked in every domain.

applying a skin

// Skins retint accent + rail only. Structure, density and state
// colors are identical across every domain.
<FractalShell skin="clep" ... />        // via the shell prop

// or scope a skin to any subtree:
<div data-skin="kiddos">{children}</div>

// core    — neutral Barton operations
// kiddos  — Personal / Kiddos
// clep    — CLEP / study systems
// svg     — Insurance Informatics / SVG Agency

6 · Block IDs

stable · never recycled

Page-block identity is separate from CTB node identity. IDs are used for admin search, validation, support notes and targeted edit requests — so they must survive reordering and renaming.

data-block-id convention

// Give every independently editable block a stable ID.
// Scope: <page>.<area>.<block> — identity is logical, not positional.
<section data-block-id="section.source-coverage">
  <h2 ...>Source coverage</h2>
</section>

<OrientationStrip blockId="page.record.orientation" ... />
<DataTable blockId="page.record.line-items" ... />

// Reordering, restyling or renaming must NOT change the ID.
// Retiring a block retires its ID — never recycle it.
// AdminBlockIdToggle overlays the badges; off for all non-admin views.

Toggle Block IDs in the header to see the overlay on this page.

7 · Rules for consumers

non-negotiable

source: workspace knowledge + barton-ui-build skill
RuleWhat it means for a consuming appHow to check it
CTB is the contractNav groups, hubs, spokes and supported sections come from the app's active CTB. Page code renders it; it does not define it.Rail nav + breadcrumb match the declared tree
Sample data is never configuration`sample-data.ts` exists to make previews inspectable. Copying it into a product app fabricates authority.No import of sample-data outside docs routes
Dashboards are read surfacesA panel renders rows the caller already fetched, plus provenance. It is not the store and must show its source mode.OrientationStrip sourceMode is set on every page
Never default to verified`state` must come from a real check. Unknown is `gap`, locked is `blocked` with a stated reason.No hardcoded state="verified" in page code
No raw color utilitiesColors, radii and density come from the semantic tokens. Raw utilities break skins and state meaning.No bg-white / text-black / bg-[#hex] in components
Nothing ships without approvalPublishing, connecting a production backend, exposing secrets or overwriting live source needs explicit Dave approval.Ask before any of those four actions