96e2d0650c965d355789d626909d5df0213e103f
Terminal Portfolio
An Arch Linux terminal-themed portfolio website with Hyprland-style TUI components, built with SvelteKit, Tailwind CSS, and Three.js.
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 pageslayout: Sizes and page margins (navbar height, container width)breakpoints: Responsive breakpoints (mobile/tablet/desktop)fonts: Font stacks and weightscolorPalette: Terminal and UI colors (semantic and base colors)terminalButtons: Terminal header buttons colors (close/minimize/maximize)terminalSettings: Typing presets, delays, cursor visibility, prompt styletuiStyle: Styling options for border, spacing, font sizes, buttons, etc.tuiText: Labels, hints, prefixes, and text labels for interactive elementsanimations: Animation durations and easing for UI interactionsscrollbar: Scrollbar appearance settingsnavbar: Navbar sizes and theme button settingsmodelViewer: 3D viewer camera, lighting, and text stringsparticles: 3D background particles (count, opacity, motion)loadingScreen: Loading text and colorskeyboardShortcuts: Map keyboard actions to keyseffects: Misc effects like selection background and backdrop blurpageMeta: Per-route metadata (title, description, icon, keywords)
Example: Key config snippets
// 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
colorPaletteto affect both inline coloring and semantic tokens like(&primary)/(&error). - Update
terminalSettingsto control typing speed, delays, and the TUI icon. - Modify
tuiStyleto adjust spacing, rounded corners, and button sizes. - Use
keyboardShortcutsto 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 typessrc/lib/components/tui/utils.ts— parsing utilities and style helperssrc/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
// 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:
'(&bg-red)Red background(&)'
'(&bg-blue,white)Blue bg with white text(&)'
'(&bg-surface)Surface background(&)'
'(&bg-#333333)Custom bg color(&)'
Text Styles
'(&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:
'(&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
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)
{
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)
{
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
{
type: 'image',
content: 'Caption text', // Optional caption
image: '/path/to/image.png',
imageAlt: 'Alt text',
imageWidth: 300, // Max width in pixels
}
Card
{
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
{
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
{
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
{
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
{
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:
<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
# 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 |
Description
Languages
Svelte
43%
TypeScript
38.7%
CSS
18%
JavaScript
0.2%
