> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metacogna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Baseline Components

> Standardized Paper UI component specifications and reference implementations

This document provides standardized component specifications for the Paper UI design system. Use these as the baseline implementation for all MetaCogna Suite applications.

## Overview

These baseline components follow Paper UI principles:

* **Digital Paper**: Physical sheets with distinct borders and hard shadows
* **Hard Edges**: Minimal border radius (max 2px)
* **High Contrast**: Strict Ink/Paper polarity

## PaperCard

The fundamental container component for content organization.

### TypeScript Interface

```typescript theme={null}
interface PaperCardProps extends HTMLMotionProps<'div'> {
  title?: string;
  headerAction?: React.ReactNode;
  children: React.ReactNode;
  noPadding?: boolean;
  className?: string;
}
```

### Implementation

```typescript theme={null}
export const PaperCard: React.FC<PaperCardProps> = ({ 
  title, 
  headerAction, 
  children, 
  className = '', 
  noPadding = false,
  ...props 
}) => {
  return (
    <motion.div 
      className={`bg-paper border-2 border-ink shadow-hard flex flex-col ${className}`}
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.4, ease: "easeOut" }}
      {...props}
    >
      {title && (
        <div className="border-b-2 border-ink bg-surface px-6 py-3 flex justify-between items-center">
          <h3 className="font-serif font-bold text-lg text-ink tracking-wide uppercase">
            {title}
          </h3>
          {headerAction && <div>{headerAction}</div>}
        </div>
      )}
      <div className={noPadding ? '' : 'p-6'}>
        {children}
      </div>
    </motion.div>
  );
};
```

### Usage

```typescript theme={null}
<PaperCard title="Card Title">
  Card content goes here
</PaperCard>

<PaperCard title="Card with Action" headerAction={<button>Action</button>}>
  Content with header action
</PaperCard>

<PaperCard noPadding>
  Content without padding
</PaperCard>
```

### Styling Specifications

* **Background**: `bg-paper` (white/light background)
* **Border**: `border-2 border-ink` (2px solid border)
* **Shadow**: `shadow-hard` (4px 4px 0px 0px)
* **Title Typography**: Serif font, bold, uppercase, tracking-wide
* **Padding**: `p-6` (default) or none if `noPadding` prop

### Dark Mode

Automatically handled via CSS custom properties:

* Paper becomes dark in dark mode
* Ink becomes light in dark mode
* Shadows adapt automatically

## PaperButton

Interactive button component with variants and sizes.

### TypeScript Interface

```typescript theme={null}
interface PaperButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
  size?: 'sm' | 'md' | 'lg';
  fullWidth?: boolean;
}
```

### Implementation

```typescript theme={null}
export const PaperButton: React.FC<PaperButtonProps> = ({ 
  children, 
  variant = 'primary', 
  size = 'md', 
  fullWidth = false,
  className = '',
  ...props 
}) => {
  const baseStyles = "font-bold font-sans border-2 border-ink transition-all duration-100 active:translate-x-[2px] active:translate-y-[2px] active:shadow-none flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed";
  
  const variants = {
    primary: "bg-ink text-paper hover:bg-accent hover:text-ink hover:border-ink shadow-hard",
    secondary: "bg-paper text-ink hover:bg-surface shadow-hard",
    ghost: "bg-transparent border-transparent hover:border-ink hover:bg-surface text-ink shadow-none hover:shadow-hard",
    danger: "bg-paper text-warning border-2 border-warning shadow-hard hover:bg-warning hover:text-paper hover:border-ink",
  };

  const sizes = {
    sm: "text-xs px-3 py-1.5",
    md: "text-sm px-5 py-2.5",
    lg: "text-base px-8 py-4",
  };

  const widthClass = fullWidth ? 'w-full' : '';

  return (
    <button 
      className={`${baseStyles} ${variants[variant]} ${sizes[size]} ${widthClass} ${className}`}
      {...props}
    >
      {children}
    </button>
  );
};
```

### Usage

```typescript theme={null}
<PaperButton variant="primary">Primary Button</PaperButton>
<PaperButton variant="secondary">Secondary Button</PaperButton>
<PaperButton variant="ghost">Ghost Button</PaperButton>
<PaperButton variant="danger">Danger Button</PaperButton>
<PaperButton size="sm">Small Button</PaperButton>
<PaperButton fullWidth>Full Width Button</PaperButton>
```

### Variants

* **primary**: Ink background, paper text, hover to accent
* **secondary**: Paper background, ink text
* **ghost**: Transparent, gains border and shadow on hover
* **danger**: Warning color border and text

### Active State

Buttons translate `2px` in both X and Y directions on click (`active:translate-x-[2px] active:translate-y-[2px]`) to simulate physical button press.

## PaperInput

Text input field with label and error support.

### TypeScript Interface

```typescript theme={null}
interface PaperInputProps extends InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
}
```

### Implementation

```typescript theme={null}
export const PaperInput: React.FC<PaperInputProps> = ({ 
  label, 
  error, 
  className = '', 
  ...props 
}) => {
  return (
    <div className={`flex flex-col gap-1.5 ${className}`}>
      {label && (
        <label className="font-mono text-xs uppercase font-bold text-ink">
          {label}
        </label>
      )}
      <input 
        className="bg-paper border-2 border-ink p-3 text-ink font-mono text-sm placeholder-gray-400 focus:outline-none focus:ring-0 focus:shadow-hard transition-all duration-200"
        {...props}
      />
      {error && (
        <span className="text-red-600 dark:text-red-400 text-xs font-mono">
          {error}
        </span>
      )}
    </div>
  );
};
```

### Usage

```typescript theme={null}
<PaperInput 
  label="USERNAME"
  placeholder="Enter username"
  value={username}
  onChange={(e) => setUsername(e.target.value)}
/>

<PaperInput 
  label="EMAIL"
  type="email"
  error="Invalid email address"
/>
```

### Styling Specifications

* **Font**: Monospace (`font-mono`) - Paper UI principle for technical inputs
* **Border**: 2px solid ink border
* **Focus**: Hard shadow (`shadow-hard`) instead of ring
* **Label**: Monospace, uppercase, bold, tracking-wide
* **Error**: Monospace font, warning color

## PaperTextArea

Multi-line text input component.

### TypeScript Interface

```typescript theme={null}
interface PaperTextAreaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
  label?: string;
  error?: string;
}
```

### Implementation

```typescript theme={null}
export const PaperTextArea: React.FC<PaperTextAreaProps> = ({ 
  label, 
  error, 
  className = '', 
  ...props 
}) => {
  return (
    <div className={`flex flex-col gap-1.5 ${className}`}>
      {label && (
        <label className="font-mono text-xs uppercase font-bold text-ink">
          {label}
        </label>
      )}
      <textarea 
        className="bg-paper border-2 border-ink p-3 text-ink font-mono text-sm placeholder-gray-400 focus:outline-none focus:ring-0 focus:shadow-hard transition-all duration-200 min-h-[120px]"
        {...props}
      />
      {error && (
        <span className="text-red-600 dark:text-red-400 text-xs font-mono">
          {error}
        </span>
      )}
    </div>
  );
};
```

### Usage

```typescript theme={null}
<PaperTextArea 
  label="DESCRIPTION"
  rows={5}
  value={description}
  onChange={(e) => setDescription(e.target.value)}
/>
```

## PaperSelect

Dropdown select component with custom styling.

### TypeScript Interface

```typescript theme={null}
interface PaperSelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
  label?: string;
  error?: string;
  options: { value: string; label: string }[];
}
```

### Implementation

```typescript theme={null}
export const PaperSelect: React.FC<PaperSelectProps> = ({ 
  label, 
  error, 
  options, 
  className = '', 
  ...props 
}) => {
  return (
    <div className={`flex flex-col gap-1.5 ${className}`}>
      {label && (
        <label className="font-mono text-xs uppercase font-bold text-ink">
          {label}
        </label>
      )}
      <div className="relative">
        <select 
          className="appearance-none w-full bg-paper border-2 border-ink p-3 text-ink font-sans focus:outline-none focus:ring-0 focus:shadow-hard transition-all duration-200"
          {...props}
        >
          {options.map(opt => (
            <option key={opt.value} value={opt.value}>
              {opt.label}
            </option>
          ))}
        </select>
        <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-ink">
          <svg className="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
            <path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
          </svg>
        </div>
      </div>
      {error && (
        <span className="text-red-600 dark:text-red-400 text-xs font-mono">
          {error}
        </span>
      )}
    </div>
  );
};
```

### Usage

```typescript theme={null}
<PaperSelect
  label="LANGUAGE"
  options={[
    { value: 'en', label: 'English' },
    { value: 'es', label: 'Spanish' },
  ]}
  value={language}
  onChange={(e) => setLanguage(e.target.value)}
/>
```

## PaperBadge

Status indicator and label component.

### TypeScript Interface

```typescript theme={null}
interface PaperBadgeProps {
  children: React.ReactNode;
  color?: 'emerald' | 'blue' | 'purple' | 'orange' | 'red' | 'gray';
}
```

### Implementation

```typescript theme={null}
export const PaperBadge: React.FC<PaperBadgeProps> = ({ 
  children, 
  color = 'gray' 
}) => {
  const colors = {
    emerald: "bg-emerald-50 dark:bg-emerald-900/50 text-emerald-800 dark:text-emerald-200 border-emerald-200 dark:border-emerald-700",
    blue: "bg-blue-50 dark:bg-blue-900/50 text-blue-800 dark:text-blue-200 border-blue-200 dark:border-blue-700",
    purple: "bg-purple-50 dark:bg-purple-900/50 text-purple-800 dark:text-purple-200 border-purple-200 dark:border-purple-700",
    orange: "bg-orange-50 dark:bg-orange-900/50 text-orange-800 dark:text-orange-200 border-orange-200 dark:border-orange-700",
    red: "bg-red-50 dark:bg-red-900/50 text-red-800 dark:text-red-200 border-red-200 dark:border-red-700",
    gray: "bg-gray-50 dark:bg-gray-800 text-gray-800 dark:text-gray-200 border-gray-200 dark:border-gray-600",
  };

  return (
    <span className={`inline-flex items-center px-2.5 py-0.5 border text-xs font-mono font-bold uppercase tracking-wider ${colors[color]}`}>
      {children}
    </span>
  );
};
```

### Usage

```typescript theme={null}
<PaperBadge color="emerald">SUCCESS</PaperBadge>
<PaperBadge color="red">ERROR</PaperBadge>
<PaperBadge color="blue">INFO</PaperBadge>
```

### Styling Specifications

* **Font**: Monospace, uppercase, bold, tracking-wider
* **Size**: `text-xs` (12px) for readability
* **Colors**: Supports semantic colors with dark mode variants

## PaperModal

Modal dialog component with overlay and animations.

### TypeScript Interface

```typescript theme={null}
interface PaperModalProps {
  isOpen: boolean;
  onClose: () => void;
  title: string;
  children: React.ReactNode;
  maxWidth?: string;
}
```

### Implementation

```typescript theme={null}
export const PaperModal: React.FC<PaperModalProps> = ({ 
  isOpen, 
  onClose, 
  title, 
  children, 
  maxWidth = "max-w-lg" 
}) => {
  return (
    <AnimatePresence>
      {isOpen && (
        <div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
          <motion.div 
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="absolute inset-0 bg-ink/30 backdrop-blur-sm"
            onClick={onClose}
          />
          <motion.div
            initial={{ opacity: 0, scale: 0.95, y: 10 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            exit={{ opacity: 0, scale: 0.95, y: 10 }}
            className={`relative z-10 w-full ${maxWidth} max-h-[95vh] overflow-y-auto`}
          >
            <PaperCard 
              title={title} 
              headerAction={
                <button onClick={onClose} className="hover:text-accent transition-colors text-ink">
                  <X className="w-5 h-5" />
                </button>
              }
            >
              {children}
            </PaperCard>
          </motion.div>
        </div>
      )}
    </AnimatePresence>
  );
};
```

### Usage

```typescript theme={null}
<PaperModal 
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  title="Modal Title"
>
  Modal content goes here
</PaperModal>
```

## Animation Guidelines

### Card Animations

Cards should use subtle fade-in animations:

```typescript theme={null}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, ease: "easeOut" }}
```

### Button Interactions

Buttons should translate on active state:

```typescript theme={null}
active:translate-x-[2px] active:translate-y-[2px] active:shadow-none
```

### Modal Animations

Modals should scale and fade:

```typescript theme={null}
initial={{ opacity: 0, scale: 0.95, y: 10 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 10 }}
```

## Dark Mode Support

All components automatically support dark mode through CSS custom properties:

* **Colors**: Defined in `:root` and `.dark` selectors
* **Components**: Use semantic tokens (`bg-paper`, `text-ink`, etc.)
* **No changes needed**: Components adapt automatically

<Note>
  Ensure your Tailwind configuration uses CSS custom properties for colors. See [Tailwind Configuration](/design/tailwind-config) for details.
</Note>

## Dependencies

Required dependencies:

```json theme={null}
{
  "dependencies": {
    "react": "^18.0.0",
    "framer-motion": "^10.0.0"
  },
  "devDependencies": {
    "tailwindcss": "^3.0.0",
    "@types/react": "^18.0.0"
  }
}
```

## Related Documentation

* [Design System](/design/system) - Paper UI design principles
* [Tailwind Configuration](/design/tailwind-config) - Setup guide
* [Component Guide](/design/components) - Usage patterns
* [Application Review](/design/application-review) - Implementation review
