@@ -4,36 +4,66 @@ An Arch Linux terminal-themed portfolio website with Hyprland-style TUI componen
## Features
## Features
- 🖥️ ** Hyprland-style TUI** - Terminal interface inspired by Textual Python TUI
- Hyprland-style TUI - Terminal interface inspired by Textual Python TUI
- 🎨 **Theme Support ** - Arch Linux and Catppuccin (Mocha/Latte) theme s
- Interactive command line - Type commands directly into the terminal to navigate and run action s
- 🌓 **Dark/Light Mode ** - Toggle between dark and light mod es
- Theme Support - Arch Linux and Catppuccin (Mocha/Latte) them es
- ⌨️ **Keyboard Navigation ** - Navigate with arrow keys or vim-style j/k
- Dark/Light Mode - Toggle between dark and light modes
- 🎮 **3D Model Viewer ** - Interactive Three.js viewer for .glb models
- Keyboard Navigation - Navigate with arrow keys or vim-style j/k
- ⚡ **Configurable Speed ** - Per-page typing animation speed
- 3D Model Viewer - Interactive Three.js viewer for .glb models
- 📱 **Responsive ** - Works on desktop and mobile
- QR Links Page - Generate a scannable QR code for any of your links
- 🎨 **Rich Text Formatting ** - Colors, backgrounds, and text decorations
- Configurable Speed - Per-page typing animation speed
- Responsive - Works on desktop and mobile
- Rich Text Formatting - Colors, backgrounds, and text decorations
## Pages
## Pages
- ** Home** (`/` ) - Neofetch-style intro with navigation
- Home (`/` ) - Neofetch-style intro with navigation
- **Portfolio** ( `/portfolio` ) - Skills, projects, and contact info
- About ( `/about` ) - Background and details
- **Models** ( `/models` ) - 3D model gallery with interactive viewer
- Portfolio ( `/portfolio` ) - Profile, experience, skills, and contact info
- **Hackathons** ( `/hackathons` ) - Hackathon projects and achievemen ts
- Projects ( `/projects` ) - Open source, packages, and h ackathon projec ts
- **Components** ( `/components` ) - Showcase of all TUI components
- Models ( `/models` ) - 3D model gallery with interactive viewer
- Components (`/components` ) - Showcase of all TUI components
- Links (`/links` ) - All links with on-demand QR codes
The navbar exposes Home, About, Portfolio, Projects, and Blog. The Models, Components, and Links pages are reachable directly by URL or with the terminal `cd` command (for example, `cd links` ).
## Terminal Commands
Every terminal page has an interactive command line at the bottom. Click the terminal (or just start typing once focused), enter a command, and press Enter. Output is printed back into the terminal.
Use the Up/Down arrows to cycle through command history.
| Command | Aliases | Description |
|---------|---------|-------------|
| `help` | `h` , `?` | List all available commands |
| `clear` | `cls` | Clear the terminal |
| `whoami` | | Show a short bio |
| `neofetch` | `banner` | Display system info |
| `skills` | | List skills by category |
| `contact` | `socials` | Show social links as buttons |
| `email` | | Open a mail draft |
| `cd <page>` | `goto` , `open` | Navigate to a page |
| `ls` | | List the pages you can visit |
| `theme [name]` | | List or set the color theme |
| `mode [dark\|light]` | | Toggle or set dark/light mode |
| `echo <text>` | | Print text back |
| `date` | | Show the current date and time |
Command definitions live in `src/lib/components/tui/terminal-commands.ts` . Add a new entry to the `commands` list to extend the command set.
## Configuration
## Configuration
The site configuration is now **modular ** — split into focused files in `src/lib/config/` for easier maintenance. You can still import everything from `$lib/config` for backward compatibility.
The site configuration is modular - split into focused files in `src/lib/config/` for easier maintenance. You can still import everything from `$lib/config` for backward compatibility.
### Config File Structure
### Config File Structure
```
```
src/lib/config/
src/lib/config/
├── index.ts # Barrel export (re-exports all modules)
├── index.ts # Barrel export (re-exports all modules)
├── user.ts # User profile, socials, skills
├── user.ts # User profile, socials, links, skills
├── layout.ts # Layout dimensions, breakpoints, fonts, navbar, scrollbar
├── layout.ts # Layout dimensions, breakpoints, fonts, navbar, scrollbar
├── theme.ts # Colors, animations, effects, loading screen
├── theme.ts # Colors, animations, effects, loading screen
├── content.ts # Projects, 3D models, hackathon cards
├── content.ts # Projects, 3D models, experience, hackathon cards
├── terminal.ts # Terminal settings, TUI styling, speed presets, shortcuts
├── terminal.ts # Terminal settings, TUI styling, speed presets, shortcuts
└── navigation.ts # Navigation links, site metadata, page meta
└── navigation.ts # Navigation links, site metadata, page meta
```
```
@@ -45,9 +75,9 @@ src/lib/config/
import { user , colorPalette , projects } from '$lib/config' ;
import { user , colorPalette , projects } from '$lib/config' ;
// Direct imports (smaller bundles, faster builds)
// Direct imports (smaller bundles, faster builds)
import { user , skills } from '$lib/config/user' ;
import { user , skills , links } from '$lib/config/user' ;
import { colorPalette , animations } from '$lib/config/theme' ;
import { colorPalette , animations } from '$lib/config/theme' ;
import { projects , models , cards } from '$lib/config/content' ;
import { openSourceProjects , cards , experience } from '$lib/config/content' ;
import { terminalSettings , keyboardShortcuts } from '$lib/config/terminal' ;
import { terminalSettings , keyboardShortcuts } from '$lib/config/terminal' ;
import { navigation , site , pageMeta } from '$lib/config/navigation' ;
import { navigation , site , pageMeta } from '$lib/config/navigation' ;
```
```
@@ -56,14 +86,15 @@ import { navigation, site, pageMeta } from '$lib/config/navigation';
| File | Contents |
| File | Contents |
|------|----------|
|------|----------|
| `user.ts` | `user` , `skills` |
| `user.ts` | `user` , `skills` , `links` |
| `layout.ts` | `layout` , `breakpoints` , `fonts` , `navbar` , `scrollbar` |
| `layout.ts` | `layout` , `breakpoints` , `fonts` , `navbar` , `scrollbar` |
| `theme.ts` | `colorPalette` , `terminalButtons` , `loadingScreen` , `effects` , `animations` |
| `theme.ts` | `colorPalette` , `terminalButtons` , `loadingScreen` , `effects` , `animations` |
| `content.ts` | `p rojects` , `models` , `cards` , `sortedCards` + types |
| `content.ts` | `openSourceProjects` , `packageP rojects` , `models` , `experience` , `cards` , `sortedCards` + types |
| `terminal.ts` | `terminalSettings` , `tuiStyle` , `tuiText` , `pageSpeedSettings` , `pageAutoscrollSettings` , `speedPresets` , `modelViewer` , `particles` , `keyboardShortcuts` |
| `terminal.ts` | `terminalSettings` , `tuiStyle` , `tuiText` , `pageSpeedSettings` , `pageAutoscrollSettings` , `speedPresets` , `modelViewer` , `particles` , `keyboardShortcuts` |
| `navigation.ts` | `navigation` , `site` , `pageMeta` |
| `navigation.ts` | `navigation` , `site` , `pageMeta` |
### Example: Key config snippets
### Example: Key config snippets
``` typescript
``` typescript
// Toggle theme keys and other shortcuts
// Toggle theme keys and other shortcuts
export const keyboardShortcuts = {
export const keyboardShortcuts = {
@@ -83,7 +114,6 @@ export const terminalSettings = {
lineDelay : 100 ,
lineDelay : 100 ,
showCursor : true ,
showCursor : true ,
promptStyle : 'full' ,
promptStyle : 'full' ,
icon : '🐧' ,
scrollMargin : 80 ,
scrollMargin : 80 ,
} ;
} ;
@@ -100,21 +130,12 @@ export const colorPalette = {
error : '#f38ba8' ,
error : '#f38ba8' ,
success : '#a6e3a1' ,
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
### How to Customize
- Edit `config/user.ts` to update your profile, socials, and skills
- Edit `config/user.ts` to update your profile, socials, links, and skills
- Edit `config/content.ts` to add projects, models, or hackathon entries
- Edit `config/content.ts` to add projects, models, experience, or hackathon entries
- Edit `config/theme.ts` to change colors, animations, or loading screen
- Edit `config/theme.ts` to change colors, animations, or loading screen
- Edit `config/terminal.ts` to adjust typing speed, TUI styling, or shortcuts
- Edit `config/terminal.ts` to adjust typing speed, TUI styling, or shortcuts
- Edit `config/layout.ts` to change dimensions, breakpoints, or navbar settings
- Edit `config/layout.ts` to change dimensions, breakpoints, or navbar settings
@@ -124,11 +145,28 @@ Changes take effect on next reload. Some values (fonts, CSS variables) may also
### Where to Look for Types & Utilities
### Where to Look for Types & Utilities
- `src/lib/config/` — All configuration modules
- `src/lib/config/` - All configuration modules
- `src/lib/components/tui/types.ts` — TerminalLine types
- `src/lib/components/tui/types.ts` - TerminalLine types
- `src/lib/components/tui/utils.ts` — Parsing utilities and style helpers
- `src/lib/components/tui/utils.ts` - Parsing utilities and style helpers
- `src/lib/stores/theme.ts` — Theme store & `toggleMode()`
- `src/lib/components/tui/terminal-commands.ts` - Interactive command definitions
- `src/lib/index.ts` — Helper functions (barrel export)
- `src/lib/stores/theme.ts` - Theme store & `toggleMode()`
- `src/lib/index.ts` - Helper functions (barrel export)
## Links Page
The `/links` page lists everything in the `links` array (a dedicated list, separate from `user.socials` ) and renders a scannable QR code for whichever link is selected, plus a clickable button to open it.
Add or remove entries in `src/lib/config/user.ts` :
``` typescript
export const links : LinkItem [ ] = [
{ name : 'GitHub' , icon : 'mdi:github' , link : 'https://github.com/SirBlobby' } ,
{ name : 'Email' , icon : 'mdi:email' , link : ` mailto: ${ user . email } ` } ,
// Add page-only links here without touching user.socials
] ;
```
QR codes are generated with the `svelte-qrcode` package, loaded on the client.
## Speed Presets
## Speed Presets
@@ -214,10 +252,10 @@ Combine multiple styles with commas:
const lines : TerminalLine [ ] = [
const lines : TerminalLine [ ] = [
{ type : 'command' , content : 'ls -la' } , // With prompt prefix
{ type : 'command' , content : 'ls -la' } , // With prompt prefix
{ type : 'output' , content : 'File listing...' } , // Muted text
{ type : 'output' , content : 'File listing...' } , // Muted text
{ type : 'error' , content : 'Error message' } , // Red with ✗ prefix
{ type : 'error' , content : 'Error message' } , // Red with prefix
{ type : 'success' , content : 'Success!' } , // Green with ✓ prefix
{ type : 'success' , content : 'Success!' } , // Green with prefix
{ type : 'info' , content : 'Information' } , // Primary with › prefix
{ type : 'info' , content : 'Information' } , // Primary with prefix
{ type : 'header' , content : 'Section Title' } , // Bold with # icon
{ type : 'header' , content : 'Section Title' } , // Bold heading
{ type : 'blank' , content : '' } , // Empty line
{ type : 'blank' , content : '' } , // Empty line
{ type : 'divider' , content : 'SECTION' , id : 'section' } , // Horizontal divider with anchor ID
{ type : 'divider' , content : 'SECTION' , id : 'section' } , // Horizontal divider with anchor ID
] ;
] ;
@@ -381,7 +419,6 @@ Groups allow you to arrange multiple elements together with custom layout:
groupDirection : 'row' , // row | column (default: row)
groupDirection : 'row' , // row | column (default: row)
groupAlign : 'start' , // start | center | end
groupAlign : 'start' , // start | center | end
groupGap : '1rem' , // CSS gap value
groupGap : '1rem' , // CSS gap value
groupGap : '1rem' , // CSS gap value
groupExpand : true , // Expand children to fill width (default: false)
groupExpand : true , // Expand children to fill width (default: false)
inline : true , // Render inline with other elements
inline : true , // Render inline with other elements
children : [
children : [
@@ -407,6 +444,7 @@ Main terminal component:
interactive = { true }
interactive = { true }
speed="normal"
speed="normal"
autoscroll = { true }
autoscroll = { true }
enableCommands= { true }
onComplete = {() => console . log ( 'Done!' )}
onComplete = {() => console . log ( 'Done!' )}
/ >
/ >
```
```
@@ -417,6 +455,7 @@ Props:
- `interactive` - Enable keyboard navigation
- `interactive` - Enable keyboard navigation
- `speed` - Typing speed preset or multiplier
- `speed` - Typing speed preset or multiplier
- `autoscroll` - Auto-scroll as content types (default: true)
- `autoscroll` - Auto-scroll as content types (default: true)
- `enableCommands` - Show the interactive command input (default: true)
- `onComplete` - Callback when typing animation finishes
- `onComplete` - Callback when typing animation finishes
### Anchor Scrolling
### Anchor Scrolling
@@ -440,8 +479,9 @@ src/lib/components/
├── terminal-api.ts # Terminal API factory for reactive control
├── terminal-api.ts # Terminal API factory for reactive control
├── terminal-typing.ts # Typing animation engine
├── terminal-typing.ts # Typing animation engine
├── terminal-keyboard.ts # Keyboard navigation handler
├── terminal-keyboard.ts # Keyboard navigation handler
├── terminal-commands.ts # Interactive command definitions
├── TuiHeader.svelte # Top status bar
├── TuiHeader.svelte # Top status bar
├── TuiBody.svelte # Scrollable content area (uses TuiLine)
├── TuiBody.svelte # Scrollable content area + command input
├── TuiFooter.svelte # Bottom status bar
├── TuiFooter.svelte # Bottom status bar
├── TuiLine.svelte # Unified line renderer for all types
├── TuiLine.svelte # Unified line renderer for all types
├── TuiGroup.svelte # Container for grouped elements
├── TuiGroup.svelte # Container for grouped elements
@@ -540,7 +580,6 @@ The `TerminalTUI` component exposes a reactive API for programmatic control via
]);
]);
async function runProcess() {
async function runProcess() {
// Update existing line
terminal ? . updateById ( 'status' , {
terminal ? . updateById ( 'status' , {
type : 'info' ,
type : 'info' ,
content : 'Processing...'
content : 'Processing...'
@@ -548,7 +587,6 @@ The `TerminalTUI` component exposes a reactive API for programmatic control via
await delay ( 1000 );
await delay ( 1000 );
// Add progress
terminal ? . write ({
terminal ? . write ({
type : 'progress' ,
type : 'progress' ,
content : '' ,
content : '' ,
@@ -558,7 +596,6 @@ The `TerminalTUI` component exposes a reactive API for programmatic control via
await delay ( 1000 );
await delay ( 1000 );
// Complete
terminal ? . updateById ( 'status' , {
terminal ? . updateById ( 'status' , {
type : 'success' ,
type : 'success' ,
content : 'Complete!'
content : 'Complete!'
@@ -575,13 +612,14 @@ The `TerminalTUI` component exposes a reactive API for programmatic control via
The `ModelViewer` component provides an interactive Three.js viewer for `.glb` models.
The `ModelViewer` component provides an interactive Three.js viewer for `.glb` models.
### Features
### Features
- ** Mouse Controls** : Drag to rotate, scroll to zoom
- Mouse Controls: Drag to rotate, scroll to zoom
- ** Arrow Key Controls** : Use arrow keys to orbit the camera (click viewer to focus first)
- Arrow Key Controls: Use arrow keys to orbit the camera (click viewer to focus first)
- ** Auto-rotate** : Toggle automatic rotation
- Auto-rotate: Toggle automatic rotation
- ** Wireframe Mode** : View model wireframe
- Wireframe Mode: View model wireframe
- ** Adjustable Lighting** : Increase/decrease scene brightness
- Adjustable Lighting: Increase/decrease scene brightness
- ** Fullscreen Mode** : Expand to full viewport (press ` Escape` to exit)
- Fullscreen Mode: Expand to full viewport (press Escape to exit)
- ** Ground Plane** : Optional shadow-receiving ground
- Ground Plane: Optional shadow-receiving ground
- Graceful Fallback: Shows an error message when WebGL is unavailable instead of crashing
### Usage
### Usage
@@ -596,11 +634,13 @@ Place `.glb` files in `/static/models/` and they'll be accessible at `/models/fi
## Tech Stack
## Tech Stack
- ** Framework** : SvelteKit 2.x with Svelte 5 runes
- Framework: SvelteKit 2.x with Svelte 5 runes
- ** Styling** : Tailwind CSS 4.x
- Styling: Tailwind CSS 4.x
- **3D** : Three.js with GLTFLoader
- 3D : Three.js with GLTFLoader
- **Icons**: @iconify/svelte
- QR codes: svelte-qrcode
- **Font**: JetBrains Mono
- Icons: @iconify/svelte
- Font: JetBrains Mono
- Runtime: Bun
## Development
## Development
@@ -614,29 +654,31 @@ bun run dev
# Build for production
# Build for production
bun run build
bun run build
# Preview production build
# Type-check
bun run preview
bun run check
```
```
## Keyboard Shortcuts
## Keyboard Shortcuts
| Key | Action |
| Key | Action |
|-----|--------|
|-----|--------|
| `↑` / `k` | Navigate up |
| Up / k | Navigate up |
| `↓` / `j` | Navigate down |
| Down / j | Navigate down |
| ` Enter` | Activate button |
| Enter | Activate button |
| `Y` | Skip typing animation |
| Y | Skip typing animation |
| `T` | Toggle dark/light mode |
| T | Toggle dark/light mode |
When the command input is focused, these keys type normally instead of triggering navigation.
### 3D Model Viewer
### 3D Model Viewer
| Key | Action |
| Key | Action |
|-----|--------|
|-----|--------|
| `←` | Rotate camera left |
| Left | Rotate camera left |
| `→` | Rotate camera right |
| Right | Rotate camera right |
| `↑` | Rotate camera up |
| Up | Rotate camera up |
| `↓` | Rotate camera down |
| Down | Rotate camera down |
| ` Escape` | Exit fullscreen |
| Escape | Exit fullscreen |
## Theme System
## Theme System
@@ -647,7 +689,7 @@ Themes are defined as JSON files in `src/lib/assets/themes/`. Each theme contain
``` json
``` json
{
{
"name" : "Theme Name" ,
"name" : "Theme Name" ,
"icon" : "🎨 " ,
"icon" : "arch " ,
"dark" : {
"dark" : {
"colors" : {
"colors" : {
"primary" : "#89b4fa" ,
"primary" : "#89b4fa" ,
@@ -673,8 +715,8 @@ Themes are defined as JSON files in `src/lib/assets/themes/`. Each theme contain
}
}
} ,
} ,
"light" : {
"light" : {
"colors" : { / * l i g h t m o d e c o l o r s * / } ,
"colors" : { } ,
"colorMap" : { / * l i g h t m o d e c o l o r m a p * / }
"colorMap" : { }
}
}
}
}
```
```
@@ -696,10 +738,6 @@ Themes are defined as JSON files in `src/lib/assets/themes/`. Each theme contain
` ``
` ``
4. Update the ` ColorTheme` type to include your theme name
4. Update the ` ColorTheme` type to include your theme name
### Available Themes
- **Arch Linux** (` arch`) - Classic terminal colors with Arch blue
- **Catppuccin** (` catppuccin`) - Soft, pastel Mocha/Latte colors
### Theme-Specific Colors
### Theme-Specific Colors
Beyond the basic colors, themes include:
Beyond the basic colors, themes include:
@@ -716,7 +754,6 @@ Beyond the basic colors, themes include:
## Mobile Considerations
## Mobile Considerations
- ** Viewport height** : Uses ` 100dvh` (dynamic viewport height) to properly handle mobile browser chrome
- Viewport height: Uses ` 100dvh` (dynamic viewport height) to properly handle mobile browser chrome
- ** Background color** : A fallback dark background (` #1e1e2e `) is set on ` html` and ` body` to prevent white bars when the page content doesn't fill the viewport
- Background color: A fallback dark background (` #1e1e2e `) is set on ` html` and ` body` to prevent white bars when the page content doesn't fill the viewport
- ** Overflow handling** : Hidden horizontal scrollbar to prevent accidental horizontal scroll on mobile
- Overflow handling: Hidden horizontal scrollbar to prevent accidental horizontal scroll on mobile