Bug Fixes and Formatting Update

This commit is contained in:
2025-11-28 05:13:49 +00:00
parent c61cb39475
commit 88b068a2b5
18 changed files with 863 additions and 199 deletions

169
README.md
View File

@@ -21,6 +21,7 @@ An Arch Linux terminal-themed portfolio website with Hyprland-style TUI componen
- **Portfolio** (`/portfolio`) - Skills, projects, and contact info
- **Models** (`/models`) - 3D model gallery with interactive viewer
- **Hackathons** (`/hackathons`) - Hackathon projects and achievements
- **Components** (`/components`) - Showcase of all TUI components
## Configuration
@@ -198,10 +199,24 @@ const lines: TerminalLine[] = [
{ 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
{ type: 'divider', content: 'SECTION', id: 'section' }, // Horizontal divider with anchor ID
];
```
### Line Properties
All line types support these optional properties:
```typescript
{
type: 'output',
content: 'Hello world',
id: 'my-section', // Anchor ID for URL hash scrolling (e.g., /page#my-section)
inline: true, // Render inline with adjacent inline elements
delay: 500, // Delay before this line appears (ms)
}
```
### Button (Full-width interactive)
```typescript
@@ -212,11 +227,28 @@ const lines: TerminalLine[] = [
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)
inline: true, // Render as compact inline button
// OR
action: () => doSomething(), // Custom action
}
```
### Inline Elements
Multiple elements can be rendered on the same line using `inline: true`:
```typescript
// These will appear on the same line
{ type: 'output', content: 'Status:', inline: true },
{ type: 'success', content: 'Online', inline: true },
{ type: 'button', content: 'Refresh', icon: 'mdi:refresh', inline: true },
// Next line without inline breaks the group
{ type: 'blank', content: '' },
```
Supported inline types: `button`, `link`, `tooltip`, `progress`, `output`, `info`, `success`, `error`, `warning`
### Link (Inline clickable text)
```typescript
@@ -322,10 +354,29 @@ Main terminal component:
title="~/directory"
interactive={true}
speed="normal"
autoscroll={true}
onComplete={() => console.log('Done!')}
/>
```
Props:
- `lines` - Array of TerminalLine objects
- `title` - Terminal window title
- `interactive` - Enable keyboard navigation
- `speed` - Typing speed preset or multiplier
- `autoscroll` - Auto-scroll as content types (default: true)
- `onComplete` - Callback when typing animation finishes
### Anchor Scrolling
Add `id` to any line to create an anchor that can be linked to:
```typescript
{ type: 'divider', content: 'SKILLS', id: 'skills' },
```
Then link to it with `/portfolio#skills` - the page will scroll to that section after typing completes.
### Component Structure
```
@@ -346,9 +397,29 @@ src/lib/components/
└── TuiTooltip.svelte # Hover tooltip
```
## 3D Models
## 3D Model Viewer
Place `.glb` files in `/static/models/` and update the models page to display them.
The `ModelViewer` component provides an interactive Three.js viewer for `.glb` models.
### Features
- **Mouse Controls**: Drag to rotate, scroll to zoom
- **Arrow Key Controls**: Use arrow keys to orbit the camera (click viewer to focus first)
- **Auto-rotate**: Toggle automatic rotation
- **Wireframe Mode**: View model wireframe
- **Adjustable Lighting**: Increase/decrease scene brightness
- **Fullscreen Mode**: Expand to full viewport (press `Escape` to exit)
- **Ground Plane**: Optional shadow-receiving ground
### Usage
```svelte
<ModelViewer
modelPath="/models/my-model.glb"
modelName="My Model"
/>
```
Place `.glb` files in `/static/models/` and they'll be accessible at `/models/filename.glb`.
## Tech Stack
@@ -384,3 +455,95 @@ bun run preview
| `Y` | Skip typing animation |
| `T` | Toggle dark/light mode |
### 3D Model Viewer
| Key | Action |
|-----|--------|
| `←` | Rotate camera left |
| `→` | Rotate camera right |
| `↑` | Rotate camera up |
| `↓` | Rotate camera down |
| `Escape` | Exit fullscreen |
## Theme System
Themes are defined as JSON files in `src/lib/assets/themes/`. Each theme contains colors for both dark and light modes.
### Theme File Structure
```json
{
"name": "Theme Name",
"icon": "🎨",
"dark": {
"colors": {
"primary": "#89b4fa",
"secondary": "#313244",
"accent": "#a6e3a1",
"background": "#1e1e2e",
"backgroundLight": "#313244",
"text": "#cdd6f4",
"textMuted": "#a6adc8",
"border": "#45475a",
"terminal": "#1e1e2e",
"terminalPrompt": "#cba6f7",
"terminalUser": "#a6e3a1",
"terminalPath": "#89b4fa"
},
"colorMap": {
"red": "#f38ba8",
"green": "#a6e3a1",
"blue": "#89b4fa",
"primary": "var(--terminal-primary)",
"accent": "var(--terminal-accent)",
"muted": "var(--terminal-muted)"
}
},
"light": {
"colors": { /* light mode colors */ },
"colorMap": { /* light mode color map */ }
}
}
```
### Adding a New Theme
1. Create a new file: `src/lib/assets/themes/mytheme.theme.json`
2. Import it in `src/lib/stores/theme.ts`:
```typescript
import myTheme from '$lib/assets/themes/mytheme.theme.json';
```
3. Add it to the themes object:
```typescript
const themes: Record<ColorTheme, ThemeJson> = {
arch: archTheme,
catppuccin: catppuccinTheme,
mytheme: myTheme as ThemeJson
};
```
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
Beyond the basic colors, themes include:
- `teal`, `sky`, `sapphire`, `lavender`
- `peach`, `maroon`, `mauve`
- `flamingo`, `rosewater`
```typescript
// These colors adapt to the current theme
'(&teal)Teal text(&)'
'(&lavender)Lavender text(&)'
'(&peach)Peach text(&)'
```
## Mobile Considerations
- **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
- **Overflow handling**: Hidden horizontal scrollbar to prevent accidental horizontal scroll on mobile