523 lines
10 KiB
Markdown
523 lines
10 KiB
Markdown
|
|
# Terminal Window Styling Guide
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The terminal now has a beautiful window frame wrapper, similar to Ghostty and other modern terminal emulators. This gives your web-based terminal a native application feel.
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
### 1. Terminal Window Frame
|
||
|
|
- **Rounded corners** (10px border radius)
|
||
|
|
- **Deep shadow** for depth and elevation
|
||
|
|
- **Frosted glass effect** with backdrop blur
|
||
|
|
- **Semi-transparent background** that shows the page background
|
||
|
|
|
||
|
|
### 2. Title Bar
|
||
|
|
- **macOS-style traffic light buttons** (close, minimize, maximize)
|
||
|
|
- **Customizable title text**
|
||
|
|
- **Subtle border** separating it from terminal content
|
||
|
|
- **40px height** for comfortable proportions
|
||
|
|
|
||
|
|
### 3. Window Controls
|
||
|
|
- **Red button** - Close (traditionally closes the window)
|
||
|
|
- **Yellow button** - Minimize (traditionally minimizes the window)
|
||
|
|
- **Green button** - Maximize (traditionally maximizes/fullscreen)
|
||
|
|
- **Hover effect** - Buttons brighten on hover
|
||
|
|
- **12px diameter** - Classic macOS size
|
||
|
|
|
||
|
|
## Customization Options
|
||
|
|
|
||
|
|
### Change Terminal Title
|
||
|
|
|
||
|
|
In `templates/term.html`, find:
|
||
|
|
|
||
|
|
```html
|
||
|
|
<div class="terminal-title">socktop - Terminal</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
Change to:
|
||
|
|
```html
|
||
|
|
<div class="terminal-title">My Awesome Terminal</div>
|
||
|
|
<div class="terminal-title">🚀 socktop v1.0</div>
|
||
|
|
<div class="terminal-title">Terminal</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adjust Window Size
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
width: 80%; /* Default: 80% of viewport */
|
||
|
|
max-width: 1200px; /* Default: 1200px max */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
width: 90%; /* Larger window */
|
||
|
|
width: 60%; /* Smaller window */
|
||
|
|
width: 1000px; /* Fixed width */
|
||
|
|
max-width: 1400px; /* Bigger max */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Change Border Radius (Roundness)
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 10px; /* Default: 10px */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
border-radius: 6px; /* Smaller, subtle */
|
||
|
|
border-radius: 15px; /* More rounded */
|
||
|
|
border-radius: 20px; /* Very rounded */
|
||
|
|
border-radius: 0; /* Square corners */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adjust Shadow Depth
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
box-shadow:
|
||
|
|
0 25px 50px rgba(0, 0, 0, 0.5),
|
||
|
|
0 10px 20px rgba(0, 0, 0, 0.3);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Light shadow:**
|
||
|
|
```css
|
||
|
|
box-shadow:
|
||
|
|
0 10px 25px rgba(0, 0, 0, 0.3),
|
||
|
|
0 5px 10px rgba(0, 0, 0, 0.2);
|
||
|
|
```
|
||
|
|
|
||
|
|
**Heavy shadow:**
|
||
|
|
```css
|
||
|
|
box-shadow:
|
||
|
|
0 40px 80px rgba(0, 0, 0, 0.6),
|
||
|
|
0 20px 40px rgba(0, 0, 0, 0.4);
|
||
|
|
```
|
||
|
|
|
||
|
|
**No shadow:**
|
||
|
|
```css
|
||
|
|
box-shadow: none;
|
||
|
|
```
|
||
|
|
|
||
|
|
### Change Title Bar Color
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-titlebar {
|
||
|
|
background: rgba(40, 40, 40, 0.95); /* Default: dark */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
/* Lighter */
|
||
|
|
background: rgba(60, 60, 60, 0.95);
|
||
|
|
|
||
|
|
/* Darker */
|
||
|
|
background: rgba(20, 20, 20, 0.95);
|
||
|
|
|
||
|
|
/* Colored (blue) */
|
||
|
|
background: rgba(30, 40, 60, 0.95);
|
||
|
|
|
||
|
|
/* Transparent */
|
||
|
|
background: rgba(40, 40, 40, 0.7);
|
||
|
|
|
||
|
|
/* Solid */
|
||
|
|
background: rgb(40, 40, 40);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Change Title Bar Height
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-titlebar {
|
||
|
|
height: 40px; /* Default */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
height: 32px; /* Compact */
|
||
|
|
height: 48px; /* Spacious */
|
||
|
|
height: 36px; /* Slightly smaller */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Customize Traffic Light Colors
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-button.close {
|
||
|
|
background: #ff5f57; /* Red */
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.minimize {
|
||
|
|
background: #ffbd2e; /* Yellow */
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.maximize {
|
||
|
|
background: #28c840; /* Green */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Alternative color schemes:**
|
||
|
|
|
||
|
|
**Windows style:**
|
||
|
|
```css
|
||
|
|
.terminal-button.close {
|
||
|
|
background: #e81123;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.minimize {
|
||
|
|
background: #0078d4;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.maximize {
|
||
|
|
background: #0078d4;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Monochrome:**
|
||
|
|
```css
|
||
|
|
.terminal-button.close {
|
||
|
|
background: #999;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.minimize {
|
||
|
|
background: #777;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button.maximize {
|
||
|
|
background: #555;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Change Button Size
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-button {
|
||
|
|
width: 12px;
|
||
|
|
height: 12px;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
width: 10px; height: 10px; /* Smaller */
|
||
|
|
width: 14px; height: 14px; /* Larger */
|
||
|
|
width: 16px; height: 16px; /* Much larger */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adjust Button Spacing
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-controls {
|
||
|
|
gap: 8px; /* Default: 8px between buttons */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
gap: 6px; /* Tighter */
|
||
|
|
gap: 10px; /* Looser */
|
||
|
|
gap: 12px; /* More space */
|
||
|
|
```
|
||
|
|
|
||
|
|
### Change Window Frame Background
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
background: rgba(30, 30, 30, 0.95); /* Default: dark */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
/* Darker */
|
||
|
|
background: rgba(20, 20, 20, 0.95);
|
||
|
|
|
||
|
|
/* Lighter */
|
||
|
|
background: rgba(50, 50, 50, 0.9);
|
||
|
|
|
||
|
|
/* Colored */
|
||
|
|
background: rgba(30, 35, 45, 0.95);
|
||
|
|
|
||
|
|
/* More transparent */
|
||
|
|
background: rgba(30, 30, 30, 0.8);
|
||
|
|
|
||
|
|
/* Fully opaque */
|
||
|
|
background: rgb(30, 30, 30);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adjust Backdrop Blur
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
backdrop-filter: blur(20px); /* Default: 20px */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Options:**
|
||
|
|
```css
|
||
|
|
backdrop-filter: blur(10px); /* Light blur */
|
||
|
|
backdrop-filter: blur(30px); /* Heavy blur */
|
||
|
|
backdrop-filter: blur(40px); /* Very heavy blur */
|
||
|
|
backdrop-filter: none; /* No blur */
|
||
|
|
```
|
||
|
|
|
||
|
|
## Window Styles Presets
|
||
|
|
|
||
|
|
### Ghostty Style (Default)
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 10px;
|
||
|
|
box-shadow:
|
||
|
|
0 25px 50px rgba(0, 0, 0, 0.5),
|
||
|
|
0 10px 20px rgba(0, 0, 0, 0.3);
|
||
|
|
background: rgba(30, 30, 30, 0.95);
|
||
|
|
backdrop-filter: blur(20px);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Minimal Style
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 6px;
|
||
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
||
|
|
background: rgba(20, 20, 20, 0.9);
|
||
|
|
backdrop-filter: blur(10px);
|
||
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Floating Style
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 15px;
|
||
|
|
box-shadow:
|
||
|
|
0 50px 100px rgba(0, 0, 0, 0.6),
|
||
|
|
0 20px 40px rgba(0, 0, 0, 0.4);
|
||
|
|
background: rgba(25, 25, 25, 0.85);
|
||
|
|
backdrop-filter: blur(30px) saturate(180%);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Flat Style
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 0;
|
||
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||
|
|
background: rgba(30, 30, 30, 0.98);
|
||
|
|
backdrop-filter: none;
|
||
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Glass Style
|
||
|
|
```css
|
||
|
|
.terminal-window {
|
||
|
|
border-radius: 12px;
|
||
|
|
box-shadow:
|
||
|
|
0 30px 60px rgba(0, 0, 0, 0.4),
|
||
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||
|
|
background: rgba(40, 40, 40, 0.7);
|
||
|
|
backdrop-filter: blur(40px) saturate(150%);
|
||
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Making Buttons Functional
|
||
|
|
|
||
|
|
Currently, the traffic light buttons are just decorative. To make them functional, add JavaScript:
|
||
|
|
|
||
|
|
### Close Button
|
||
|
|
```javascript
|
||
|
|
document.querySelector('.terminal-button.close').addEventListener('click', () => {
|
||
|
|
if (confirm('Close terminal?')) {
|
||
|
|
window.close(); // Or your custom close logic
|
||
|
|
}
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### Minimize Button
|
||
|
|
```javascript
|
||
|
|
document.querySelector('.terminal-button.minimize').addEventListener('click', () => {
|
||
|
|
document.querySelector('.terminal-window').style.transform = 'scale(0.5)';
|
||
|
|
// Or hide: document.querySelector('.terminal-window').style.display = 'none';
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### Maximize Button
|
||
|
|
```javascript
|
||
|
|
let isMaximized = false;
|
||
|
|
document.querySelector('.terminal-button.maximize').addEventListener('click', () => {
|
||
|
|
const window = document.querySelector('.terminal-window');
|
||
|
|
if (isMaximized) {
|
||
|
|
window.style.width = '80%';
|
||
|
|
window.style.maxHeight = '50vh';
|
||
|
|
} else {
|
||
|
|
window.style.width = '100%';
|
||
|
|
window.style.maxHeight = '100vh';
|
||
|
|
}
|
||
|
|
isMaximized = !isMaximized;
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## Hide Traffic Lights
|
||
|
|
|
||
|
|
If you prefer no window controls:
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-controls {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-title {
|
||
|
|
text-align: left; /* Since there's no buttons on the left */
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Center Title Without Controls
|
||
|
|
|
||
|
|
```css
|
||
|
|
.terminal-title {
|
||
|
|
text-align: center;
|
||
|
|
margin: 0 auto;
|
||
|
|
width: 100%;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Add Icons to Title
|
||
|
|
|
||
|
|
```html
|
||
|
|
<div class="terminal-title">
|
||
|
|
<span>⚡</span> socktop - Terminal
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="terminal-title">
|
||
|
|
<span style="font-size: 16px;">💻</span> Terminal
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Title Bar Variations
|
||
|
|
|
||
|
|
### Left-aligned title with icon
|
||
|
|
```html
|
||
|
|
<div class="terminal-titlebar">
|
||
|
|
<div class="terminal-controls">...</div>
|
||
|
|
<div class="terminal-title" style="text-align: left; flex: 1;">
|
||
|
|
<span style="margin-right: 8px;">🚀</span>
|
||
|
|
socktop v1.0
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Title with tabs (like modern terminals)
|
||
|
|
```html
|
||
|
|
<div class="terminal-titlebar">
|
||
|
|
<div class="terminal-controls">...</div>
|
||
|
|
<div style="display: flex; gap: 4px; flex: 1;">
|
||
|
|
<div class="terminal-tab active">Terminal 1</div>
|
||
|
|
<div class="terminal-tab">Terminal 2</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
```
|
||
|
|
|
||
|
|
Then add CSS:
|
||
|
|
```css
|
||
|
|
.terminal-tab {
|
||
|
|
padding: 8px 16px;
|
||
|
|
background: rgba(255, 255, 255, 0.05);
|
||
|
|
border-radius: 6px 6px 0 0;
|
||
|
|
color: rgba(255, 255, 255, 0.5);
|
||
|
|
font-size: 12px;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-tab.active {
|
||
|
|
background: rgba(255, 255, 255, 0.1);
|
||
|
|
color: rgba(255, 255, 255, 0.9);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Responsive Behavior
|
||
|
|
|
||
|
|
The window automatically adjusts on mobile:
|
||
|
|
|
||
|
|
```css
|
||
|
|
@media (max-width: 640px) {
|
||
|
|
.terminal-window {
|
||
|
|
width: 96%;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Customize:
|
||
|
|
```css
|
||
|
|
@media (max-width: 768px) {
|
||
|
|
.terminal-window {
|
||
|
|
width: 100%;
|
||
|
|
border-radius: 0; /* Remove rounded corners on mobile */
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-titlebar {
|
||
|
|
height: 36px; /* Smaller on mobile */
|
||
|
|
}
|
||
|
|
|
||
|
|
.terminal-button {
|
||
|
|
width: 10px;
|
||
|
|
height: 10px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Accessibility
|
||
|
|
|
||
|
|
The title bar is set to `user-select: none` so users can't accidentally select the text when clicking the buttons.
|
||
|
|
|
||
|
|
To make buttons keyboard accessible:
|
||
|
|
```html
|
||
|
|
<div class="terminal-button close" role="button" tabindex="0" aria-label="Close"></div>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Browser Compatibility
|
||
|
|
|
||
|
|
All features work in modern browsers:
|
||
|
|
- ✅ Chrome/Edge 76+
|
||
|
|
- ✅ Safari 9+
|
||
|
|
- ✅ Firefox 103+
|
||
|
|
|
||
|
|
`backdrop-filter` gracefully degrades in older browsers (window will just be more opaque).
|
||
|
|
|
||
|
|
## Performance Tips
|
||
|
|
|
||
|
|
1. **Reduce blur** if experiencing lag: `blur(10px)` instead of `blur(20px)`
|
||
|
|
2. **Simplify shadows** on low-end devices
|
||
|
|
3. **Use opacity carefully** - too many transparent layers can impact performance
|
||
|
|
|
||
|
|
## Quick Reference
|
||
|
|
|
||
|
|
```css
|
||
|
|
/* Size */
|
||
|
|
width: 80%;
|
||
|
|
max-width: 1200px;
|
||
|
|
border-radius: 10px;
|
||
|
|
|
||
|
|
/* Colors */
|
||
|
|
background: rgba(30, 30, 30, 0.95);
|
||
|
|
titlebar: rgba(40, 40, 40, 0.95);
|
||
|
|
|
||
|
|
/* Effects */
|
||
|
|
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
|
||
|
|
backdrop-filter: blur(20px);
|
||
|
|
|
||
|
|
/* Buttons */
|
||
|
|
close: #ff5f57 (red)
|
||
|
|
minimize: #ffbd2e (yellow)
|
||
|
|
maximize: #28c840 (green)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Enjoy your beautiful terminal window frame!** 🖼️✨
|