# Terminal Portfolio

An Arch Linux terminal-themed portfolio website with Hyprland-style TUI components, built with SvelteKit, Tailwind CSS, and Three.js.

![Terminal Portfolio](./static/og-image.png)

## Features

- 🖥️ **Hyprland-style TUI** - Terminal interface inspired by Textual Python TUI
- 🎨 **Theme Support** - Arch Linux and Catppuccin (Mocha/Latte) themes
- 🌓 **Dark/Light Mode** - Toggle between dark and light modes
- ⌨️ **Keyboard Navigation** - Navigate with arrow keys or vim-style j/k
- 🎮 **3D Model Viewer** - Interactive Three.js viewer for .glb models
- ⚡ **Configurable Speed** - Per-page typing animation speed
- 📱 **Responsive** - Works on desktop and mobile
- 🎨 **Rich Text Formatting** - Colors, backgrounds, and text decorations

## Pages

- **Home** (`/`) - Neofetch-style intro with navigation
- **Portfolio** (`/portfolio`) - Skills, projects, and contact info
- **Models** (`/models`) - 3D model gallery with interactive viewer
- **Hackathons** (`/hackathons`) - Hackathon projects and achievements

## Configuration

Everything in the site is configurable from `src/lib/config.ts`. This file is the single source of truth for UI, layout, TUI behavior, colors, and per-page settings. Edit it to personalize the website to your needs.

### Main Config Sections
- `user`: Profile info (name, username, bio, social links)
- `skills`, `projects`, `models`, `hackathons`: Content arrays shown in pages
- `layout`: Sizes and page margins (navbar height, container width)
- `breakpoints`: Responsive breakpoints (mobile/tablet/desktop)
- `fonts`: Font stacks and weights
- `colorPalette`: Terminal and UI colors (semantic and base colors)
- `terminalButtons`: Terminal header buttons colors (close/minimize/maximize)
- `terminalSettings`: Typing presets, delays, cursor visibility, prompt style
- `tuiStyle`: Styling options for border, spacing, font sizes, buttons, etc.
- `tuiText`: Labels, hints, prefixes, and text labels for interactive elements
- `animations`: Animation durations and easing for UI interactions
- `scrollbar`: Scrollbar appearance settings
- `navbar`: Navbar sizes and theme button settings
- `modelViewer`: 3D viewer camera, lighting, and text strings
- `particles`: 3D background particles (count, opacity, motion)
- `loadingScreen`: Loading text and colors
- `keyboardShortcuts`: Map keyboard actions to keys
- `effects`: Misc effects like selection background and backdrop blur
- `pageMeta`: Per-route metadata (title, description, icon, keywords)

### Example: Key config snippets
```typescript
// Toggle theme keys and other shortcuts
export const keyboardShortcuts = {
  skip: ['y', 'Y'],           // Skip typing animation
  toggleTheme: ['t', 'T'],    // Toggle dark/light mode
  navigateUp: ['ArrowUp', 'k'],
  navigateDown: ['ArrowDown', 'j'],
  select: ['Enter'],
};

// Terminal / typing
export const terminalSettings = {
  baseTypeSpeed: 20,
  minTypeSpeed: 5,
  maxTypeSpeed: 50,
  startDelay: 300,
  lineDelay: 100,
  showCursor: true,
  promptStyle: 'full',
  icon: '🐧',
  scrollMargin: 80,
};

// Color palette (Catppuccin Mocha by default)
export const colorPalette = {
  red: '#f38ba8',
  green: '#a6e3a1',
  yellow: '#f9e2af',
  blue: '#89b4fa',
  magenta: '#cba6f7',
  cyan: '#94e2d5',
  white: '#cdd6f4',
  gray: '#6c7086',
  error: '#f38ba8',
  success: '#a6e3a1',
};

// TUI styling example
export const tuiStyle = {
  borderRadius: 8,
  borderWidth: 2,
  width: '95%',
  bodyPadding: '1rem 1.25rem 2rem 1.25rem',
  buttonPadding: '0.5rem 0.75rem',
};
```

### How to customize
- Change any color in `colorPalette` to affect both inline coloring and semantic tokens like `(&primary)`/`(&error)`.
- Update `terminalSettings` to control typing speed, delays, and the TUI icon.
- Modify `tuiStyle` to adjust spacing, rounded corners, and button sizes.
- Use `keyboardShortcuts` to remap keys (e.g., toggle theme, skip animation).
- Per-page speeds are controlled by `pageSpeedSettings` (preset or numeric multiplier).

### Where to look for types & utilities
- `src/lib/components/tui/types.ts` — main TerminalLine types
- `src/lib/components/tui/utils.ts` — parsing utilities and style helpers
- `src/lib/stores/theme.ts` — theme store & `toggleMode()`

If you change a value in `config.ts`, the UI should pick it up on next reload. Some values (fonts, CSS variables) may also require adjusting CSS variables or Tailwind config.

## Speed Presets

| Preset | Effect |
|--------|--------|
| `instant` | No animation, appears immediately |
| `fast` | 3x faster than normal |
| `normal` | Default typing speed |
| `slow` | 2x slower than normal |
| `typewriter` | 3x slower, classic feel |

## Text Formatting

Use inline formatting with the `(&specs)text(&)` syntax:

### Colors

```typescript
// Basic colors
'(&red)Red text(&)'
'(&green)Green text(&)'
'(&blue)Blue text(&)'
'(&yellow)Yellow text(&)'
'(&magenta)Magenta text(&)'
'(&cyan)Cyan text(&)'
'(&orange)Orange text(&)'
'(&pink)Pink text(&)'
'(&gray)Gray text(&)'
'(&white)White text(&)'

// Semantic colors (theme-aware)
'(&primary)Primary color(&)'
'(&accent)Accent color(&)'
'(&muted)Muted text(&)'
'(&error)Error text(&)'
'(&success)Success text(&)'
'(&warning)Warning text(&)'
'(&info)Info text(&)'

// Custom hex colors
'(&#ff6b6b)Custom color(&)'
```

### Background Colors

Add `bg-` prefix to any color:

```typescript
'(&bg-red)Red background(&)'
'(&bg-blue,white)Blue bg with white text(&)'
'(&bg-surface)Surface background(&)'
'(&bg-#333333)Custom bg color(&)'
```

### Text Styles

```typescript
'(&bold)Bold text(&)'
'(&italic)Italic text(&)'
'(&dim)Dimmed text (60% opacity)(&)'
'(&underline)Underlined text(&)'
'(&strikethrough)Strikethrough text(&)'
'(&strike)Strikethrough shorthand(&)'
'(&overline)Overlined text(&)'
```

### Combining Styles

Combine multiple styles with commas:

```typescript
'(&bold,red)Bold red text(&)'
'(&italic,cyan,underline)Italic cyan underlined(&)'
'(&bg-blue,white,bold)Bold white on blue(&)'
'(&dim,strikethrough,gray)Dim gray strikethrough(&)'
```

## Line Types

### Basic Lines

```typescript
const lines: TerminalLine[] = [
  { type: 'command', content: 'ls -la' },           // With prompt prefix
  { type: 'output', content: 'File listing...' },   // Muted text
  { type: 'error', content: 'Error message' },      // Red with ✗ prefix
  { type: 'success', content: 'Success!' },         // Green with ✓ prefix
  { type: 'info', content: 'Information' },         // Primary with › prefix
  { type: 'header', content: 'Section Title' },     // Bold with # icon
  { type: 'blank', content: '' },                   // Empty line
  { type: 'divider', content: 'SECTION' },          // Horizontal divider
];
```

### Button (Full-width interactive)

```typescript
{
  type: 'button',
  content: 'Click me',
  icon: 'mdi:github',           // Iconify icon
  style: 'primary',             // primary | accent | warning | error
  href: 'https://github.com',   // URL to navigate to
  external: true,               // Open in new tab (auto-detected for http/https)
  // OR
  action: () => doSomething(),  // Custom action
}
```

### Link (Inline clickable text)

```typescript
{
  type: 'link',
  content: 'Visit GitHub',
  icon: 'mdi:github',           // Optional icon
  style: 'accent',              // Styling
  href: 'https://github.com',
  external: true,               // Open in new tab (auto-detected for http/https)
}
```

### Image

```typescript
{
  type: 'image',
  content: 'Caption text',      // Optional caption
  image: '/path/to/image.png',
  imageAlt: 'Alt text',
  imageWidth: 300,              // Max width in pixels
}
```

### Card

```typescript
{
  type: 'card',
  content: 'Card body text with (&bold)formatting(&) support',
  cardTitle: 'Card Title',      // Optional header
  cardFooter: 'Footer text',    // Optional footer
  icon: 'mdi:star',             // Optional header icon
  image: '/path/to/image.png',  // Optional card image
  style: 'primary',             // Border accent color
}
```

### Progress Bar

```typescript
{
  type: 'progress',
  content: 'Loading assets...',  // Label above bar
  progress: 75,                  // 0-100 percentage
  progressLabel: '75%',          // Custom label (defaults to percentage)
  style: 'accent',               // Bar color
}
```

### Accordion

```typescript
{
  type: 'accordion',
  content: '',
  accordionItems: [
    { title: 'Section 1', content: 'Content for section 1 with (&cyan)colors(&)' },
    { title: 'Section 2', content: 'Content for section 2' },
  ],
  accordionOpen: true,           // First item open by default
  style: 'primary',              // Accent color
}
```

### Table

```typescript
{
  type: 'table',
  content: 'Table Title',        // Optional title
  tableHeaders: ['Name', 'Role', 'Status'],
  tableRows: [
    ['Alice', 'Developer', '(&success)Active(&)'],
    ['Bob', 'Designer', '(&warning)Away(&)'],
  ],
  style: 'accent',               // Header color
}
```

### Tooltip

```typescript
{
  type: 'tooltip',
  content: 'Hover me',           // Trigger text
  tooltipText: 'This is helpful information!',
  tooltipPosition: 'top',        // top | bottom | left | right
  style: 'info',                 // Tooltip border color
}
```

## TUI Components

### TerminalTUI

Main terminal component:

```svelte
<TerminalTUI 
  lines={lines}
  title="~/directory"
  interactive={true}
  speed="normal"
  onComplete={() => console.log('Done!')}
/>
```

### Component Structure

```
src/lib/components/
├── TerminalTUI.svelte      # Main terminal container
└── tui/
    ├── types.ts            # TypeScript types
    ├── utils.ts            # Parsing & styling utilities
    ├── TuiHeader.svelte    # Top status bar
    ├── TuiBody.svelte      # Scrollable content area
    ├── TuiFooter.svelte    # Bottom status bar
    ├── TuiButton.svelte    # Full-width button
    ├── TuiLink.svelte      # Inline clickable link
    ├── TuiCard.svelte      # Card with header/body/footer
    ├── TuiProgress.svelte  # Animated progress bar
    ├── TuiAccordion.svelte # Collapsible sections
    ├── TuiTable.svelte     # Data table with headers
    └── TuiTooltip.svelte   # Hover tooltip
```

## 3D Models

Place `.glb` files in `/static/models/` and update the models page to display them.

## Tech Stack

- **Framework**: SvelteKit 2.x with Svelte 5 runes
- **Styling**: Tailwind CSS 4.x
- **3D**: Three.js with GLTFLoader
- **Icons**: @iconify/svelte
- **Font**: JetBrains Mono

## Development

```bash
# Install dependencies
bun install

# Start dev server
bun run dev

# Build for production
bun run build

# Preview production build
bun run preview
```

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `↑` / `k` | Navigate up |
| `↓` / `j` | Navigate down |
| `Enter` | Activate button |
| `Y` | Skip typing animation |
| `T` | Toggle dark/light mode |

