diff --git a/AGENTS.md b/AGENTS.md index 5a2f7e6..59ccf64 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,375 +1,687 @@ -# BESPOKE GENERALIZED COMPONENTS - IMPLEMENTATION CONTEXT +# CodeSignal Design System - Agent Reference Guide -This document provides precise implementation instructions for creating embedded applications using the Bespoke generalized components. Follow these instructions exactly to ensure consistency across all applications. +This document provides comprehensive information for agentic code generators to effectively use the CodeSignal Design System. -## REQUIRED FILES STRUCTURE +## Table of Contents -Every application MUST include these files in the following order: +1. [System Overview](#system-overview) +2. [Installation & Setup](#installation--setup) +3. [Design Tokens](#design-tokens) +4. [Components](#components) +5. [Usage Patterns](#usage-patterns) +6. [Best Practices](#best-practices) +7. [File Structure](#file-structure) -1. bespoke.css (core styling framework) -2. help-modal.js (help system) -3. app.js (application logic) -4. server.js (server) +--- -## HTML TEMPLATE IMPLEMENTATION +## System Overview -1. REPLACE the following placeholders in index.html EXACTLY as specified: +The CodeSignal Design System is a CSS-based design system organized into **Foundations** (design tokens) and **Components** (reusable UI elements). All components are built using CSS custom properties (CSS variables) for theming and consistency. - a) `` - Replace with your application's page title - Example: "Database Designer" or "Task Manager" +### Key Principles - b) `` - Replace with your application's display name (appears in header) - Example: "Database Designer" or "Task Manager" +- **Semantic over Primitive**: Always prefer semantic tokens (e.g., `--Colors-Text-Body-Default`) over base scale tokens +- **Dark Mode Support**: All components automatically adapt to dark mode via `@media (prefers-color-scheme: dark)` +- **CSS-First**: Components are primarily CSS-based with minimal JavaScript (only Dropdown requires JS) +- **Accessibility**: Components follow WCAG guidelines and support keyboard navigation - c) `` - Add your application's main content area - Example: `
` or `
` +--- - d) `` - Add links to your application-specific CSS files - Example: `` +## Installation & Setup - e) `` - Add links to your application-specific JavaScript files - Example: `` +### Required CSS Files (Load in Order) -3. DO NOT modify the core structure (header, script loading order, etc.) +```html + + + + + + + + + + + + + + + + + +``` -## CSS IMPLEMENTATION +### Alternative: CSS Import -1. ALWAYS use the `.bespoke` class on the body element -2. USE ONLY the provided CSS custom properties for styling: - - Colors: `--bespoke-bg`, `--bespoke-fg`, `--bespoke-accent`, etc. - - Spacing: `--bespoke-space-xs` through `--bespoke-space-2xl` - - Typography: `--bespoke-font-size-*`, `--bespoke-font-weight-*` - - Borders: `--bespoke-radius-*`, `--bespoke-stroke` - - Shadows: `--bespoke-shadow-*` +```css +@import url('/design-system/colors/colors.css'); +@import url('/design-system/spacing/spacing.css'); +@import url('/design-system/typography/typography.css'); +@import url('/design-system/components/button/button.css'); +``` -3. FOR custom styling, create app-specific CSS files -4. OVERRIDE variables in your app-specific CSS, not in bespoke.css -5. FOLLOW the existing naming conventions for consistency +### JavaScript (Only for Dropdown) -## JAVASCRIPT IMPLEMENTATION +```html + +``` -1. HELP MODAL SETUP: - a) Create help content using help-content-template.html as reference - b) Initialize HelpModal with: - - triggerSelector: `'#btn-help'` - - content: your help content (string or loaded from file) - - theme: `'auto'` +--- -2. STATUS MANAGEMENT: - a) Use the provided setStatus() function for status updates - b) Update status for: loading, saving, errors, user actions - c) Keep status messages concise and informative +## Design Tokens -## ERROR HANDLING REQUIREMENTS +### Colors -1. WRAP all async operations in try-catch blocks -2. PROVIDE meaningful error messages to users -3. LOG errors to console for debugging -4. IMPLEMENT retry logic for network operations -5. HANDLE localStorage quota exceeded errors -6. VALIDATE data before saving operations +#### Base Scales (Primitive Tokens) +**Avoid using these directly** - use semantic tokens instead for theming support. -## STATUS MESSAGE CONVENTIONS +Pattern: `--Colors-Base-[Family]-[Step]` -Use these EXACT status messages for consistency: +**Families:** +- `Primary`: Brand blue colors (20-1400 scale) +- `Neutral`: Grays, white, black (00-1400 scale) +- `Accent-Green`: Success states +- `Accent-Sky-Blue`: Info states +- `Accent-Yellow`: Warning states +- `Accent-Orange`: Warning states +- `Accent-Red`: Error/Danger states -- "Ready" - Application loaded successfully -- "Loading..." - Data is being loaded -- "Saving..." - Data is being saved -- "Changes saved" - Auto-save completed successfully -- "Save failed (will retry)" - Server save failed, will retry -- "Failed to load data" - Data loading failed -- "Auto-save initialized" - Auto-save system started +**Example:** +```css +--Colors-Base-Primary-700: #1062FB; +--Colors-Base-Neutral-600: #ACB4C7; +--Colors-Base-Accent-Green-600: #10B981; +``` + +#### Semantic Tokens (Preferred) +**Always use these** for automatic dark mode support and consistency. + +**Categories:** + +1. **Primary Colors** + - `--Colors-Primary-Default` + - `--Colors-Primary-Medium` + - `--Colors-Primary-Strong` + +2. **Backgrounds** + - `--Colors-Backgrounds-Main-Default` + - `--Colors-Backgrounds-Main-Top` + - `--Colors-Backgrounds-Main-Medium` + - `--Colors-Backgrounds-Main-Strong` + +3. **Text Colors** + - `--Colors-Text-Body-Default` + - `--Colors-Text-Body-Secondary` + - `--Colors-Text-Body-Medium` + - `--Colors-Text-Body-Strong` + - `--Colors-Text-Body-Strongest` + +4. **Icon Colors** + - `--Colors-Icon-Default` + - `--Colors-Icon-Primary` + - `--Colors-Icon-Secondary` + +5. **Stroke/Border Colors** + - `--Colors-Stroke-Default` + - `--Colors-Stroke-Strong` + - `--Colors-Stroke-Strongest` + +6. **Alert Colors** + - `--Colors-Alert-Success-Default`, `--Colors-Alert-Success-Medium` + - `--Colors-Alert-Error-Default`, `--Colors-Alert-Error-Medium` + - `--Colors-Alert-Warning-Default`, `--Colors-Alert-Warning-Medium` + - `--Colors-Alert-Info-Default`, `--Colors-Alert-Info-Medium` + +### Spacing + +Pattern: `--UI-Spacing-spacing-[size]` + +**Available Sizes:** +- `none`: 0 +- `min`: 2px +- `xxs`: 4px +- `xs`: 6px +- `s`: 8px +- `mxs`: 12px +- `ms`: 16px +- `m`: 18px +- `ml`: 20px +- `mxl`: 24px +- `l`: 28px +- `xl`: 32px +- `xxl`: 36px +- `xxxl`: 48px +- `4xl`: 60px +- `max`: 90px + +**Usage:** +```css +padding: var(--UI-Spacing-spacing-m); +margin: var(--UI-Spacing-spacing-s); +gap: var(--UI-Spacing-spacing-mxl); +``` + +### Border Radius -## FILE NAMING CONVENTIONS +Pattern: `--UI-Radius-radius-[size]` -1. CSS files: kebab-case (e.g., my-app.css, task-manager.css) -2. JavaScript files: kebab-case (e.g., my-app.js, task-manager.js) -3. Data files: kebab-case (e.g., solution.json, initial-data.json) -4. Image files: kebab-case (e.g., overview.png, help-icon.svg) +**Available Sizes:** +- `none`: 0 +- `min`: 2px +- `xxs`: 4px +- `xs`: 6px +- `s`: 8px +- `m`: 12px +- `ml`: 16px +- `mxl`: 20px +- `l`: 24px +- `xl`: 32px + +**Usage:** +```css +border-radius: var(--UI-Radius-radius-m); +``` + +### Input Heights + +Pattern: `--UI-Input-[size]` + +**Available Sizes:** +- `min`: 26px +- `xs`: 32px +- `sm`: 40px +- `md`: 48px (default) +- `lg`: 60px + +**Usage:** +```css +height: var(--UI-Input-md); +``` + +### Typography + +#### Font Families +- **Body & Labels**: `Work Sans` (sans-serif) - Must be loaded from Google Fonts +- **Headings**: `Founders Grotesk` (sans-serif) - Included via `@font-face` +- **Code**: `JetBrains Mono` (monospace) - Included via `@font-face` + +#### Typography Classes + +**Body Text** (Work Sans): +- `.body-xxsmall` (13px) +- `.body-xsmall` (14px) +- `.body-small` (15px) +- `.body-medium` (16px) +- `.body-large` (17px) +- `.body-xlarge` (19px) +- `.body-xxlarge` (21px) +- `.body-xxxlarge` (24px) + +**Body Elegant** (Founders Grotesk): +- `.body-elegant-xxsmall` (22px) +- `.body-elegant-xsmall` (26px) +- `.body-elegant-small` (32px) +- `.body-elegant-medium` (38px) + +**Headings** (Founders Grotesk, 500 weight): +- `.heading-xxxsmall` (16px) +- `.heading-xxsmall` (22px) +- `.heading-xsmall` (22px) +- `.heading-small` (24px) +- `.heading-medium` (32px) +- `.heading-large` (38px) +- `.heading-xlarge` (48px) +- `.heading-xxlarge` (64px) + +**Labels** (Work Sans, 600 weight, uppercase): +- `.label-small` (10px) +- `.label-medium` (11px) +- `.label-large` (14px) + +**Label Numbers** (Work Sans, 500 weight): +- `.label-number-xsmall` (11px) +- `.label-number-small` (12px) +- `.label-number-medium` (14px) +- `.label-number-large` (15px) --- -# BESPOKE CSS SELECTOR GUIDELINES +## Components -This section explains how to use the Bespoke CSS framework for embedded applications. +### Button -## OVERVIEW -The Bespoke CSS framework provides a scoped, reusable set of components that can be embedded in any website without conflicts. All styles are scoped under the `.bespoke` class to prevent interference with parent site styles. +**Base Class:** `.button` (required) -## BASIC USAGE +**Variants:** +- `.button-primary`: Primary action (Brand Blue background) +- `.button-secondary`: Secondary action (Outlined style) +- `.button-tertiary`: Tertiary/Ghost (Subtle background) +- `.button-danger`: Destructive action (Red) +- `.button-success`: Positive action (Green) +- `.button-text`: Text button (Neutral text, no background) +- `.button-text-primary`: Primary text button (Brand color text) -### 1. Include the CSS +**Sizes:** +- `.button-xsmall`: 32px height +- `.button-small`: 40px height +- Default: 48px height (medium) +- `.button-large`: 60px height + +**States:** +- Standard pseudo-classes: `:hover`, `:focus`, `:active`, `:disabled` +- Utility classes: `.hover`, `.focus`, `.active`, `.disabled` + +**Example:** ```html - + + + ``` -### 2. Wrap Your Application +**Dependencies:** colors.css, spacing.css, typography.css + +--- + +### Box + +**Base Class:** `.box` (required) + +**Variants:** +- `.box.selected`: Selected state (Primary border) +- `.box.emphasized`: Emphasized state (Neutral border) +- `.box.shadowed`: Soft shadow +- `.box.card`: Card-style shadow + +**States:** +- Standard pseudo-classes: `:hover`, `:focus`, `:active` +- Utility classes: `.hover`, `.focus`, `.selected` + +**Example:** ```html -
- -
+
Default content
+
Selected content
+
Card content
``` -### 3. Use the Component Classes +**Dependencies:** colors.css, spacing.css + +--- + +### Input + +**Base Class:** `.input` (required) + +**Input Types:** +- `type="text"`: Standard text input (default) +- `type="number"`: Numeric input with styled spinner buttons + +**States:** +- Standard pseudo-classes: `:hover`, `:focus`, `:disabled` +- Utility classes: `.hover`, `.focus` + +**Features:** +- Automatic focus ring (primary color with reduced opacity) +- Styled number input spinners +- Dark mode support + +**Example:** ```html -
-
-

My App

-
Ready
-
- -
- - -
- -
-
-
+ + + ``` -## COMPONENT REFERENCE +**Dependencies:** colors.css, spacing.css, typography.css + +--- + +### Tag + +**Base Class:** `.tag` or `.tag.default` (required) -### LAYOUT COMPONENTS +**Variants:** +- `.tag` / `.tag.default`: Primary tag (Brand Blue background) +- `.tag.secondary`: Secondary tag (Neutral gray background) +- `.tag.outline`: Outline tag (Transparent with border) +- `.tag.success`: Success tag (Green background) +- `.tag.error`: Error tag (Red background) +- `.tag.warning`: Warning tag (Yellow background) +- `.tag.info`: Info tag (Sky Blue background) -#### Header +**States:** +- Standard pseudo-classes: `:hover`, `:focus`, `:active` +- Utility classes: `.hover`, `.focus`, `.active` + +**Example:** ```html -
-

App Title

-
Status message
- -
+
Default
+
Completed
+
Failed
+
Filter
``` -#### Main Layout (Sidebar + Content) +**Dependencies:** colors.css, spacing.css, typography.css + +--- + +### Icon + +**Base Class:** `.icon` (required) + +**Icon Names:** +Use `.icon-[name]` where `[name]` is derived from SVG filename (e.g., `Icon=Academy.svg` → `.icon-academy`) + +**Available Icons** (80+ icons): +- `.icon-academy` +- `.icon-assessment` +- `.icon-interview` +- `.icon-jobs` +- `.icon-course` +- ... (see `icons.css` for full list) + +**Sizes:** +- `.icon-small`: 16px +- `.icon-medium`: 24px (default) +- `.icon-large`: 32px +- `.icon-xlarge`: 48px + +**Colors:** +- Default: Uses `currentColor` (inherits text color) +- `.icon-primary`: Primary brand color +- `.icon-secondary`: Secondary neutral color +- `.icon-success`: Success green color +- `.icon-danger`: Danger red color +- `.icon-warning`: Warning yellow color + +**Implementation Note:** +Icons use `mask-image` with `background-color` for color control. SVGs in data URIs use black fills (black = visible in mask). + +**Example:** ```html -
- -
- -
-
+ + + ``` -#### Cards -```html -
-

Card Title

-

Subtitle

-

Card content goes here

-
+**Dependencies:** colors.css, spacing.css + +--- + +### Dropdown (JavaScript Component) + +**Import:** +```javascript +import Dropdown from '/design-system/components/dropdown/dropdown.js'; ``` -### FORM COMPONENTS +**Initialization:** +```javascript +const dropdown = new Dropdown(selector, options); +``` -#### Labels -```html - - - - - +**Configuration Options:** + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `items` | Array | `[]` | Array of `{value, label}` objects | +| `placeholder` | String | `'Select option'` | Placeholder text | +| `selectedValue` | String | `null` | Initial selected value | +| `width` | String/Number | `'auto'` | Fixed width (ignored if `growToFit` is true) | +| `growToFit` | Boolean | `false` | Auto-resize to fit content | +| `onSelect` | Function | `null` | Callback `(value, item)` on selection | + +**API Methods:** +- `getValue()`: Returns current selected value +- `setValue(value)`: Sets selected value programmatically +- `open()`: Opens dropdown menu +- `close()`: Closes dropdown menu +- `toggleOpen()`: Toggles open state +- `destroy()`: Removes event listeners and clears container + +**Example:** +```javascript +const dropdown = new Dropdown('#my-dropdown', { + placeholder: 'Choose an option', + items: [ + { value: '1', label: 'Option 1' }, + { value: '2', label: 'Option 2' }, + { value: '3', label: 'Option 3' } + ], + onSelect: (value, item) => { + console.log('Selected:', value, item); + } +}); + +// Later... +dropdown.setValue('2'); +const currentValue = dropdown.getValue(); ``` -#### Input Fields +**Dependencies:** colors.css, spacing.css, typography.css + +--- + +## Usage Patterns + +### Component Composition + +Components can be combined and nested: + ```html - - - - - - - - - - -
- - + + + + +
+ + Completed
- -
- - + +
+ +
+``` + +### Custom Styling + +You can extend components using CSS custom properties: - - - - - +```css +.my-custom-button { + /* Inherit button styles */ + composes: button button-primary; + + /* Override with custom properties */ + --Colors-Base-Primary-700: #custom-color; +} ``` -#### Buttons -```html - - +### Responsive Design - - - - +Use standard CSS media queries with design tokens: - -Link Button +```css +@media (max-width: 768px) { + .responsive-box { + padding: var(--UI-Spacing-spacing-s); + } +} ``` -### MODAL COMPONENTS +--- + +## Best Practices + +### 1. Token Usage -#### Basic Modal +✅ **DO:** +```css +color: var(--Colors-Text-Body-Default); +padding: var(--UI-Spacing-spacing-m); +border-radius: var(--UI-Radius-radius-m); +``` + +❌ **DON'T:** +```css +color: #333; +padding: 16px; +border-radius: 8px; +``` + +### 2. Component Classes + +✅ **DO:** ```html - + ``` -## CUSTOMIZATION +❌ **DON'T:** +```html + +``` -### CSS Custom Properties -You can override any CSS custom property to customize the appearance: +### 3. Dark Mode + +✅ **DO:** Use semantic tokens (automatic dark mode) +```css +background: var(--Colors-Backgrounds-Main-Default); +``` +❌ **DON'T:** Use hardcoded colors ```css -.bespoke { - /* Override colors */ - --bespoke-bg: #f0f0f0; - --bespoke-fg: #333333; - --bespoke-accent: #ff6b6b; +background: #ffffff; +``` - /* Override spacing */ - --bespoke-space-lg: 1.5rem; +### 4. File Loading Order - /* Override border radius */ - --bespoke-radius-lg: 12px; -} +✅ **DO:** Load foundations before components +```html + + + + + + + ``` -### Available Custom Properties - -#### Colors -- `--bespoke-bg`: Background color -- `--bespoke-fg`: Text color -- `--bespoke-muted`: Muted text color -- `--bespoke-box`: Container/surface background -- `--bespoke-stroke`: Border color -- `--bespoke-danger`: Error/danger color -- `--bespoke-accent`: Accent/primary color -- `--bespoke-control-bg`: Input/button background -- `--bespoke-control-border`: Input/button border -- `--bespoke-control-focus`: Focus ring color - -#### Spacing -- `--bespoke-space-xs`: 0.25rem -- `--bespoke-space-sm`: 0.5rem -- `--bespoke-space-md`: 0.75rem -- `--bespoke-space-lg`: 1rem -- `--bespoke-space-xl`: 1.5rem -- `--bespoke-space-2xl`: 2rem - -#### Border Radius -- `--bespoke-radius-sm`: 4px -- `--bespoke-radius-md`: 6px -- `--bespoke-radius-lg`: 8px -- `--bespoke-radius-xl`: 12px - -#### Shadows -- `--bespoke-shadow-sm`: Small shadow -- `--bespoke-shadow-md`: Medium shadow -- `--bespoke-shadow-lg`: Large shadow -- `--bespoke-shadow-xl`: Extra large shadow - -## THEME SUPPORT - -### Automatic Dark Mode -The framework automatically detects the user's system preference and switches between light and dark themes. No additional configuration is needed. - -## INTEGRATION EXAMPLES - -### Database Designer +### 5. Icon Usage + +✅ **DO:** ```html -
-
-

DB Schema Designer

- -
Ready
- -
- -
- - -
- -
-
-
+ ``` -## BEST PRACTICES -1. **Always wrap in `.bespoke`**: This prevents style conflicts with the parent site -2. **Use semantic HTML**: Combine with proper HTML elements for accessibility -3. **Customize via CSS variables**: Don't modify the core CSS file -4. **Test in both themes**: Ensure your app works in light and dark modes +❌ **DON'T:** Use inline SVG or img tags for icons +```html +icon +``` + +### 6. Accessibility + +- Always include proper `alt` text for images +- Use semantic HTML (`