# Source Design System :: Full Reference Source is a personal design system to code and integrate accessible, logical, and consistent web interfaces quickly, especially in AI-assisted workflows. Two npm packages: CSS design tokens and React 18 components with TypeScript. Repository: https://github.com/pierredelattre/source-design-system --- ## Packages @pierredelattre/source-tokens CSS custom properties following the W3C DTCG spec. Dark mode via @media (prefers-color-scheme: dark) and .dark class. Accent themes via data-source-theme attribute. File: packages/tokens/index.css @pierredelattre/source-react React 18 components with TypeScript types, built on the token layer. Exports: Accordion, AccordionItem, Avatar, AvatarGroup, Badge, Breadcrumb, BreadcrumbItem, Button, Checkbox, Chip, FeatureCard, FormGroup, Input, Link, List, ListItem, Modal, Radio, RadioGroup, Select, Spinner, Switch, Tab, TabPanel, Tabs, Tag, Textarea, Toast, ToastProvider, Tooltip, useToast --- ## Install npm install @pierredelattre/source-react @pierredelattre/source-tokens --- ## Quick start import '@pierredelattre/source-tokens'; import '@pierredelattre/source-react/styles'; import { Accordion, AccordionItem, Avatar, AvatarGroup, Badge, Breadcrumb, BreadcrumbItem, Button, Checkbox, Chip, FeatureCard, FormGroup, Input, Link, List, ListItem, Modal, Radio, RadioGroup, Select, Spinner, Switch, Tab, TabPanel, Tabs, Tag, Textarea, Toast, ToastProvider, Tooltip, useToast } from '@pierredelattre/source-react'; --- ## Token conventions Naming: --source-- Two levels: 1. Primitives :: raw values: --source-neutral-900: #1D1B1A 2. Semantic :: reference primitives by role: --source-color-text: var(--source-neutral-900) Rules: - Semantic tokens reference primitives only. Never semantic-to-semantic. - Dark mode overrides semantic tokens only, via @media and .dark. - Primitives are constant across modes and themes. --- ## Color tokens File: packages/tokens/tokens/colors.css ### Neutral primitives --source-neutral-0: #FFFFFF --source-neutral-50: #FAF8F5 --source-neutral-100: #F2EEE8 --source-neutral-200: #E5DFD8 --source-neutral-300: #CBC6BF --source-neutral-400: #A9A39D --source-neutral-500: #89847F --source-neutral-600: #686462 --source-neutral-700: #4C4946 --source-neutral-800: #302F2C --source-neutral-900: #1D1B1A --source-neutral-950: #0E0D0C ### Success primitives --source-success-0: #F0FDF4 --source-success-50: #DCFCE7 --source-success-100: #BBF7D0 --source-success-200: #86EFAC --source-success-300: #4ADE80 --source-success-400: #22C55E --source-success-500: #16A34A --source-success-600: #15803D --source-success-700: #166534 --source-success-800: #14532D --source-success-900: #052E16 --source-success-950: #022212 ### Warning primitives --source-warning-0: #FFFDF5 --source-warning-50: #FFF5D6 --source-warning-100: #FEF0C0 --source-warning-200: #FDE280 --source-warning-300: #FCC53C --source-warning-400: #F5A800 --source-warning-500: #DC8A00 --source-warning-600: #B86A00 --source-warning-700: #924D00 --source-warning-800: #703500 --source-warning-900: #522200 --source-warning-950: #2A1100 ### Info primitives --source-info-0: #F5F8FF --source-info-50: #E8F0FF --source-info-100: #D5E5FF --source-info-200: #A6C4FF --source-info-300: #6EA0FF --source-info-400: #3678FF --source-info-500: #0F62FE --source-info-600: #0043CE --source-info-700: #002D9C --source-info-800: #001D6C --source-info-900: #001141 --source-info-950: #000820 ### Danger primitives --source-danger-0: #FFF5F5 --source-danger-50: #FFE6E6 --source-danger-100: #FFD7D9 --source-danger-200: #FFB3B8 --source-danger-300: #FF8389 --source-danger-400: #FA4D56 --source-danger-500: #DA1E28 --source-danger-600: #A2191F --source-danger-700: #750E13 --source-danger-800: #520408 --source-danger-900: #3B0000 --source-danger-950: #1C0000 ### Semantic color tokens Light mode values (dark mode overrides these same token names): --source-color-bg: var(--source-neutral-50) --source-color-surface: var(--source-neutral-0) --source-color-surface-raised: var(--source-neutral-100) --source-color-border: var(--source-neutral-200) --source-color-border-strong: var(--source-neutral-300) --source-color-text: var(--source-neutral-900) --source-color-text-secondary: var(--source-neutral-600) --source-color-text-label: var(--source-neutral-500) --source-color-text-disabled: var(--source-neutral-400) --source-color-text-subtle: var(--source-neutral-400) --source-color-text-inverse: var(--source-neutral-0) --source-color-success: var(--source-success-600) --source-color-success-subtle: var(--source-success-50) --source-color-warning: var(--source-warning-600) --source-color-warning-subtle: var(--source-warning-50) --source-color-info: var(--source-info-600) --source-color-info-subtle: var(--source-info-100) --source-color-danger: var(--source-danger-500) --source-color-danger-subtle: var(--source-danger-50) --source-color-background: var(--source-color-bg) --source-color-bg-default: var(--source-color-bg) --source-color-surface-default: var(--source-color-surface) --source-color-border-default: var(--source-color-border) --source-color-text-default: var(--source-color-text) --source-color-status-success-default: var(--source-color-success) --source-color-status-success-subtle: var(--source-color-success-subtle) --source-color-status-warning-default: var(--source-color-warning) --source-color-status-warning-subtle: var(--source-color-warning-subtle) --source-color-status-info-default: var(--source-color-info) --source-color-status-info-subtle: var(--source-color-info-subtle) --source-color-status-danger-default: var(--source-color-danger) --source-color-status-danger-subtle: var(--source-color-danger-subtle) Dark mode overrides: --source-color-bg: var(--source-neutral-950) --source-color-surface: var(--source-neutral-900) --source-color-surface-raised: var(--source-neutral-800) --source-color-border: var(--source-neutral-700) --source-color-border-strong: var(--source-neutral-600) --source-color-text: var(--source-neutral-50) --source-color-text-secondary: var(--source-neutral-400) --source-color-text-label: var(--source-neutral-500) --source-color-text-disabled: var(--source-neutral-600) --source-color-text-subtle: var(--source-neutral-600) --source-color-text-inverse: var(--source-neutral-900) --source-color-success: var(--source-success-400) --source-color-success-subtle: var(--source-success-900) --source-color-warning: var(--source-warning-400) --source-color-warning-subtle: var(--source-warning-900) --source-color-info: var(--source-info-400) --source-color-info-subtle: var(--source-info-900) --source-color-danger: var(--source-danger-400) --source-color-danger-subtle: var(--source-danger-900) ### Accent system Apply data-source-theme on html or body. No JS required. Available themes: blue (default), green, red, orange, yellow, pink, purple, teal Semantic accent tokens (resolved per active theme): --source-color-accent: main interactive color (button backgrounds, links) --source-color-accent-subtle: tinted background (badges, chips, highlights) --source-color-accent-text: text on neutral backgrounds in the accent hue --source-color-accent-foreground: text on the accent color itself Orange and yellow themes use deeper stops in light mode to meet contrast requirements. --- ## Typography tokens File: packages/tokens/tokens/typography.css ### Font families --source-font-sans: 'Inter', system-ui, -apple-system, sans-serif --source-font-mono: ui-monospace, 'SF Mono', 'Fira Code', monospace ### Font sizes --source-text-xs: 0.75rem (0.75rem) --source-text-sm: 0.875rem (0.875rem) --source-text-base: 1rem (1rem) --source-text-lg: 1.125rem (1.125rem) --source-text-xl: 1.25rem (1.25rem) --source-text-2xl: 1.5rem (1.5rem) --source-text-3xl: 1.875rem (1.875rem) --source-text-4xl: 2.25rem (2.25rem) ### Font weights --source-font-normal: 400 --source-font-medium: 500 --source-font-semibold: 600 ### Line heights --source-leading-tight: 1.25 --source-leading-normal: 1.5 --- ## Spacing tokens File: packages/tokens/tokens/spacing.css Scale: 4px base unit. --source-spacing-1: 4px --source-spacing-2: 8px --source-spacing-3: 12px --source-spacing-4: 16px --source-spacing-5: 20px --source-spacing-6: 24px --source-spacing-8: 32px --source-spacing-10: 40px --source-spacing-12: 48px --source-spacing-16: 64px --source-spacing-20: 80px --source-spacing-24: 96px --- ## Radius tokens File: packages/tokens/tokens/radius.css --source-radius-sm: 4px --source-radius-md: 8px --source-radius-lg: 12px --source-radius-xl: 16px --source-radius-2xl: 24px --source-radius-full: 9999px --- ## Components ### Badge File: packages/react/src/components/Badge/Badge.tsx CSS class: .source-badge Compact status marker for lifecycle state, intent, and short counters. Props: children: ReactNode (required) :: badge label palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') variant: 'subtle' | 'solid' | 'outline' (default: 'subtle') className: string :: extra class on the root element Usage: Beta Deprecated Component tokens (override on .source-badge or a parent): --source-badge-bg: --source-color-surface-raised --source-badge-color: --source-color-text-secondary --source-badge-border-color: --source-color-border --source-badge-padding-x: 0.375rem --source-badge-padding-y: 0.125rem --source-badge-font-size: 0.6875rem --source-badge-radius: --source-radius-full Accessibility: Static element. Color alone does not convey status :: always include text. --- ### Tag File: packages/react/src/components/Tag/Tag.tsx CSS class: .source-tag Category label for taxonomy and metadata. Renders as text or link. Props: children: ReactNode (required) :: tag label palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') href: string :: if set, renders an anchor element external: boolean (default: false) :: opens linked tag in a new tab className: string :: extra class on the root element Usage: Design React Accessibility Component tokens (override on .source-tag or a parent): --source-tag-bg: transparent --source-tag-color: --source-color-text-secondary --source-tag-border-color: --source-color-border-strong --source-tag-border-color-hover: --source-color-text --source-tag-padding-x: 0.5rem --source-tag-padding-y: 0.1875rem --source-tag-font-size: --source-text-xs --source-tag-radius: --source-radius-full Accessibility: Static when no href. Link text should describe the destination. --- ### Chip File: packages/react/src/components/Chip/Chip.tsx CSS class: .source-chip Interactive compact control for toggles and filter selection. Props: children: ReactNode (required) :: chip label selected: boolean (default: false) :: sets selected visuals and aria-pressed disabled: boolean (default: false) :: disables interaction palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') leadingIcon: ReactNode :: optional icon before text trailingIcon: ReactNode :: optional icon after text onClick: MouseEventHandler className: string Usage: setActiveOnly(!activeOnly)}> Active only Component tokens (override on .source-chip or a parent): --source-chip-bg: --source-color-surface --source-chip-bg-hover: --source-color-surface-raised --source-chip-bg-selected: --source-color-surface-raised --source-chip-color: --source-color-text-secondary --source-chip-color-selected: --source-color-text --source-chip-border-color: --source-color-border --source-chip-border-color-hover: --source-color-border-strong --source-chip-border-color-selected: --source-color-border-strong --source-chip-padding-x: 0.625rem --source-chip-padding-y: 0.3125rem --source-chip-font-size: --source-text-sm --source-chip-radius: --source-radius-full --source-chip-icon-size: 0.875rem Accessibility: Renders as a button element. aria-pressed reflects selected state. Disabled chips are not keyboard-reachable. --- ### Link File: packages/react/src/components/Link/Link.tsx CSS class: .source-link Inline text link with a border-bottom underline. Props: href: string (required) :: link destination children: ReactNode (required) :: link text palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') external: boolean (default: false) :: opens in new tab, adds rel="noopener noreferrer", shows arrow icon className: string Usage: Read the docs View on GitHub Component tokens (override on .source-link or a parent): --source-link-color: --source-color-text-secondary --source-link-color-hover: --source-color-text --source-link-border-color: --source-color-border-strong --source-link-border-color-hover: --source-color-text Accessibility: Standard anchor element. For external links, consider adding visible "(opens in new tab)" context for screen reader users when the destination is critical. --- ### FeatureCard File: packages/react/src/components/FeatureCard/FeatureCard.tsx CSS class: .source-feature-card Composable card for key destinations, integrations, and overview links. Renders as a link or a static block, with optional icon, subtitle, badge, and metadata. Props: title: ReactNode (required) :: main card title description: ReactNode :: supporting text subtitle: ReactNode :: secondary label under the title meta: ReactNode :: metadata line (URL, command, identifier) badge: ReactNode :: small status badge next to title icon: ReactNode :: icon in the leading icon container href: string :: if set, renders an anchor element external: boolean (default: false) :: adds target="_blank", rel="noopener noreferrer", external icon disabled: boolean (default: false) :: renders non-interactive with disabled styling palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') className: string Usage: } palette="accent" external /> Component tokens (override on .source-feature-card or a parent): --source-feature-card-bg: --source-color-surface --source-feature-card-bg-icon: --source-color-surface-raised --source-feature-card-border-color: --source-color-border --source-feature-card-border-color-hover: --source-color-border-strong --source-feature-card-title-color: --source-color-text --source-feature-card-subtitle-color: --source-color-text-secondary --source-feature-card-description-color: --source-color-text-secondary --source-feature-card-meta-color: --source-color-text-disabled --source-feature-card-icon-color: --source-color-text-secondary --source-feature-card-badge-color: --source-color-text-secondary --source-feature-card-badge-bg: --source-color-surface-raised --source-feature-card-padding: --source-spacing-5 --source-feature-card-gap: --source-spacing-3 --source-feature-card-icon-size: 32px Accessibility: Static when no href. Link mode: title text must be descriptive. External cards open a new tab with no automatic announcement. --- ### Tabs File: packages/react/src/components/Tabs/Tabs.tsx CSS classes: .source-tabs (container), .source-tab (button), .source-tab-panel (panel) Compound component for switching between related content panels. Supports controlled and uncontrolled modes. Animated sliding indicator. Props :: Tabs: defaultTab: string (default: '') :: initial active tab id, uncontrolled mode activeTab: string :: controlled active tab id onTabChange: (id: string) => void :: fired when active tab changes palette: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' (default: 'neutral') children: ReactNode (required) :: Tab and TabPanel elements className: string Props :: Tab: id: string (required) :: matches id on the corresponding TabPanel children: ReactNode (required) :: label shown in the tab button className: string Props :: TabPanel: id: string (required) :: matches id on the corresponding Tab children: ReactNode (required) :: content shown when this panel is active className: string Usage (uncontrolled): Overview Code Overview content Code content Usage (controlled): const [active, setActive] = useState('overview'); Overview Code Overview content Code content Component tokens (override on .source-tabs or a parent): --source-tab-color: --source-color-text-secondary --source-tab-color-hover: --source-color-text --source-tab-color-active: --source-color-text --source-tab-bg-hover: --source-color-surface-raised --source-tab-bg-active: --source-color-surface-raised --source-tab-border-color: --source-color-border --source-tab-indicator-color: --source-color-text --source-tab-indicator-height: 2px --source-tab-radius: --source-radius-sm --source-tab-font-size: --source-text-sm --source-tab-font-weight-active: 500 --source-tab-padding-x: --source-spacing-4 --source-tab-padding-y: --source-spacing-2 Accessibility: Implements the WAI-ARIA 1.2 Tabs pattern. role="tablist" on container, role="tab" on each button. aria-selected set to "true" on the active tab, "false" on all others. Inactive panels hidden with the boolean hidden attribute. Keyboard: Tab (focus in/out), Arrow Left/Right (cycle tabs), Home/End (first/last), Enter/Space (activate). --- ### Accordion Collapsible disclosure component using native details and summary semantics. Key props: Accordion.variant, AccordionItem.title, AccordionItem.defaultOpen, AccordionItem.disabled. Usage: Content ### Avatar Identity marker with image-first fallback to initials, then icon. Key props: Avatar.src, Avatar.name, Avatar.size, Avatar.palette, AvatarGroup.max. Usage: ### Breadcrumb Path navigation showing hierarchy and current page context. Key props: Breadcrumb.separator, BreadcrumbItem.href, BreadcrumbItem.current. Usage: HomeDocs ### Button Primary action control with variant, size, palette, and loading states. Key props: variant, size, palette, loading, href, external. Usage: ### Checkbox Boolean selection control with optional indeterminate state. Key props: checked/defaultChecked, indeterminate, label, hint, palette. Usage: ### FormGroup Layout shell for labels, hints, and error messages around custom controls. Key props: label, hint, error, required, htmlFor, children. Usage: ### Input Single-line text field with label, hint, error, and icon slots. Key props: type, label, hint, error, size, leadingIcon, trailingIcon. Usage: ### List General-purpose list wrapper with interactive or static item rows. Key props: List.variant, List.as, ListItem.label, ListItem.description, ListItem.href/onClick. Usage: ### Modal Controlled dialog overlay rendered in a portal with native dialog behavior. Key props: open, onClose, title, footer, size, closeOnBackdrop. Usage: ... ### Radio and RadioGroup Single-selection options powered by group context. Key props: RadioGroup.name/value/onChange, orientation, palette; Radio.value, label, hint. Usage: ### Select Styled native select with optional placeholder, label, hint, and error. Key props: children, placeholder, size, label, hint, error. Usage: ### Spinner SVG loading indicator with semantic palettes and four sizes. Key props: size, palette, label. Usage: ### Switch Checkbox-based toggle control for immediate on and off settings. Key props: checked/defaultChecked, label, hint, palette, size. Usage: ### Textarea Multi-line text input with matching label, hint, and error shell patterns. Key props: rows, resize, label, hint, error. Usage: