Compare commits

31 Commits

Author SHA1 Message Date
Zane V
c52173544d Update macOS support message to 'kinda supported' 2025-11-17 22:34:53 -05:00
Zane V
a3f714b5c0 Add logo image to README
Added an image to the README for visual enhancement.
2025-11-16 23:32:08 -05:00
Zane V
d5539d788a Add images section to README 2025-11-16 23:29:35 -05:00
Zane V
4f00ad57e5 Added img for README 2025-11-16 23:27:23 -05:00
0330ca768d Revamp README.md to provide comprehensive documentation for ZDTT Terminal
- Expanded the README to include detailed features, installation instructions, usage guidelines, and plugin system information.
- Introduced sections on command history, tab completion, custom aliases, and status bar functionality.
- Clarified system support and configuration options, enhancing user understanding and accessibility.
2025-11-16 18:55:04 -05:00
aa7cb5105f Update release version to v0.1.2.b.5 in index.html and version.txt 2025-11-16 18:01:27 -05:00
ee998cf77a Update release version to v0.1.2.b.4; enhance index.html with additional supported platforms and security features in terminal.py to block dangerous commands and paths 2025-11-16 16:56:48 -05:00
4e1f56802c Update release version to v0.1.2.b.3 in index.html and version.txt; enhance install.sh with improved shell detection and PATH configuration checks 2025-11-16 16:27:16 -05:00
0334133c78 Update release version to v0.1.2.b.2 in index.html and version.txt 2025-11-16 16:21:23 -05:00
16a1db487a Add 'zdtt github' command to install.sh for opening the ZDTT GitHub repository
- Implemented a new command in install.sh that opens the ZDTT GitHub repository in the user's default web browser based on the operating system.
- Updated the help text to include the new command, improving user access to the repository.
- Removed the previous 'github' command from terminal.py to streamline functionality and avoid redundancy.
2025-11-16 14:29:43 -05:00
37e5d1c6a1 Add 'github' command to terminal.py for opening the ZDTT GitHub repository
- Introduced a new command 'github' that opens the ZDTT GitHub repository in the default web browser.
- Updated the help text to include the new command, enhancing user accessibility to the repository.
- Implemented error handling for browser opening failures, providing users with a fallback URL in case of issues.
2025-11-16 14:26:47 -05:00
d483fee544 Enhance install.sh to support dynamic shell configuration detection
- Added logic to detect the user's shell (bash or zsh) and update the appropriate configuration file for PATH modification.
- Improved user prompts to reflect the detected shell configuration file.
- Implemented checks to prevent duplicate PATH entries and create the configuration file if it doesn't exist.
2025-11-16 14:12:05 -05:00
a9ee4f8866 Update release version to v0.1.2.b.1 and enhance macOS support in terminal.py and install.sh
- Updated the release version in index.html and version.txt to v0.1.2.b.1.
- Added macOS detection and installation instructions for Python 3 in install.sh.
- Refactored terminal.py to include first-class support for macOS, updating distribution prompts and compatibility checks.
- Improved user experience by integrating Homebrew installation prompts for Python 3 on macOS.
2025-11-16 14:07:13 -05:00
c9b2be1724 Update release version to v0.1.2.b and refactor terminal.py for improved functionality
- Updated the release version in index.html and version.txt to v0.1.2.b.
- Refactored terminal.py to consolidate system detection and plugin management functionalities, enhancing code organization and maintainability.
- Removed deprecated modules and streamlined the command execution process for better performance.
2025-11-16 11:11:18 -05:00
7f06853544 Add dynamic import handling for 'zdtt' package in terminal.py
- Implemented a mechanism to ensure the 'zdtt' package is importable from both repository and installed locations.
- Added a fallback search for the package in various candidate directories if the initial import fails, enhancing compatibility and usability.
2025-11-16 10:51:32 -05:00
884288a2c4 Update release version to v0.1.2.a.9 in index.html and version.txt 2025-11-16 10:48:17 -05:00
a9d4d98c4c Refactor terminal.py to enhance plugin management and system compatibility
- Moved various functions related to plugin validation and quarantine to the zdtt.plugins module for better organization and reusability.
- Updated the handling of protected commands to source from the plugins module.
- Refactored status bar management functions to utilize the zdtt.status_bar module, improving code clarity and separation of concerns.
- Simplified the display banner and compatibility warning functions by delegating to the zdtt.ui module.
- Enhanced the command execution process by integrating shell command execution from the zdtt.shell module.
2025-11-16 10:47:24 -05:00
1af1d5338b Update release version to v0.1.2.a.8 in index.html and version.txt 2025-11-15 20:58:03 -05:00
b8ff46f8af Enhance plugin security and trust management in terminal.py
- Introduced a mechanism to manage trusted plugins, allowing them to use imports safely.
- Updated loading and saving of trusted plugins in the configuration file.
- Implemented user prompts for trust confirmation when plugins request to use imports, enhancing security measures for plugin execution.
2025-11-15 20:55:38 -05:00
4d53a201b4 Update to version v0.1.2.a.7 and implement auto-update feature in install.sh
- Updated index.html and version.txt to reflect the new release version v0.1.2.a.7.
- Added an auto-update option in install.sh to streamline the update process without user prompts.
- Modified terminal.py to support the new auto-update flag during updates.
2025-11-15 19:42:02 -05:00
16970b0866 Update to version v0.1.2.a.6 and enhance plugin security in terminal.py
- Updated index.html and version.txt to reflect the new release version v0.1.2.a.6.
- Introduced security measures for plugin loading in terminal.py, including AST validation and quarantine for unsafe plugins.
- Added a safe mode option to prevent plugin loading, enhancing overall security.
2025-11-15 19:36:21 -05:00
edb1ada059 Revise terminal compatibility and update HTML content
- Updated index.html to reflect that ZDTT is now Linux-only, removing references to macOS.
- Modified descriptions and prompts in terminal.py to clarify support for only Debian-based and Arch Linux systems.
- Removed macOS-specific installation instructions and checks from the terminal code.
2025-11-15 18:35:43 -05:00
e48dd33a96 Update current release version to v0.1.2.a.5 in index.html 2025-11-15 17:50:46 -05:00
132fb8e8e0 Update version to v0.1.2.a.5 in version.txt 2025-11-15 17:50:20 -05:00
1bced7c89e Enhance macOS support in terminal.py and update index.html
- Updated compatibility messages and descriptions to include macOS support.
- Modified user prompts and checks to accommodate macOS installation requirements.
- Revised HTML content to reflect the expanded support for macOS alongside Debian and Arch.
2025-11-15 17:47:21 -05:00
5d7de5d9a6 Implement distro preference loading and saving in terminal.py
- Added functions to load and save the user's distribution preference from a config file.
- Updated check_system_compatibility to utilize saved preferences, reducing user prompts.
- Enhanced load_preferences method to include loading of distro settings.
2025-11-15 17:10:25 -05:00
566552ffee Update version to v0.1.2.a.4 in index.html and version.txt 2025-11-15 17:04:38 -05:00
d9fe4f258d Refactor terminal command execution and update help text
- Replaced the -oszdtt flag with an auto shell fallback for unknown commands.
- Introduced a new method for executing system commands with real-time I/O streaming.
- Enhanced error handling for command execution and improved user feedback.
2025-11-15 15:59:45 -05:00
750c35a652 Add favicon to index.html 2025-11-15 15:45:09 -05:00
dca47ab1eb Update version to v0.1.2.a.3 and enhance UI/UX features
- Updated version number in version.txt.
- Improved smooth scrolling for anchor links in script.js.
- Added Intersection Observer for fade-in animations in script.js.
- Enhanced CSS styles for various elements, including buttons, metrics, and backgrounds for better visual appeal and interactivity.
2025-11-15 13:52:40 -05:00
Zane V
193a434b32 Delete __pycache__/terminal.cpython-313.pyc 2025-11-15 11:27:50 -05:00
11 changed files with 2236 additions and 232 deletions

355
PLUGINS.md Normal file
View File

@@ -0,0 +1,355 @@
# 📘 **ZDTT Plugin Development Guide**
*Create safe, powerful extensions for the ZDTT Terminal.*
---
## 🟦 Introduction
ZDTT supports a secure, sandboxed plugin system that allows developers to extend the terminal with custom commands.
Plugins live inside:
```
~/.zdtt/plugins/
```
A plugin is simply a Python file that:
1. Contains **no top-level executable code**
2. Defines functions or classes
3. Defines a mandatory function:
```python
def register_commands():
return { "command": callable }
```
Plugins are automatically loaded when ZDTT starts or when you run:
```
plugins reload
```
---
# 🛡️ Plugin Security Model
ZDTT has strict safety validation to protect users from malicious plugins.
Every plugin must pass **six security layers**:
---
## **1. AST Validation**
At load time, ZDTT parses the plugin using Pythons AST.
Allowed at the top level:
* Imports
* From-imports
* Function definitions
* Class definitions
* A file-level docstring
Forbidden (**causes quarantine**):
* Print statements
* Assignments
* Function calls
* Loops
* Try/except blocks
* Any executable code
* Anything that runs automatically
Example of an unsafe plugin:
```python
print("hacked!") # ❌ this will be quarantined
os.system("rm -rf /") # ❌ also quarantined
```
Unsafe plugins are moved to:
```
~/.zdtt/quarantine/
```
---
## **2. Import Trust Prompt**
Plugins may import modules:
```python
import os
import subprocess
```
However:
**Any plugin with imports triggers a trust confirmation.**
If the user does **not** trust the plugin, it is quarantined.
If the user approves, the plugin name is added to:
```
config.json → trusted_plugins
```
Only trusted plugins may use `__import__`.
---
## **3. Sandboxed Execution**
Plugins run inside a restricted environment:
* Only safe builtins are exposed
* Dangerous builtins (like `exec` or `eval`) are blocked
* Imports only work for trusted plugins
* Code cannot escape the sandbox
---
## **4. register_commands() Validation**
Every plugin must define:
```python
def register_commands():
return {"name": function}
```
ZDTT verifies:
* The function exists
* The return value is a dict
* All values are callable
* Command names are valid strings
---
## **5. Protected Command Names**
Plugins **cannot override** important commands such as:
```
ssh, sudo, su, cp, mv, rm, ls, cat,
chmod, chown, history, zps, zdtt,
pip, python, python3, curl, wget
```
Attempting to override them causes quarantine.
---
## **6. Runtime Registration**
Once the plugin passes all previous checks, ZDTT adds its commands to the shell environment.
Example:
```python
{
"weather": cmd_weather,
"hello": cmd_hello
}
```
These appear in autocomplete and `help`.
---
# 🟩 Plugin Structure
A minimal valid plugin:
```python
"""
My Plugin
"""
def cmd_test(args):
print("Hello from ZDTT plugin!")
def register_commands():
return {"test": cmd_test}
```
---
# 🟧 Arguments
ZDTT passes command arguments as a list.
Example:
```
hello world how are you
```
Results in:
```python
cmd_hello(["world", "how", "are", "you"])
```
---
# 🟪 Example Plugin (Official)
From `example_plugin.py`:
```python
"""
Example ZDTT Plugin
"""
import subprocess
import os
def cmd_hello(args):
...
def cmd_weather(args):
...
def cmd_sysinfo(args):
...
def register_commands():
return {
"hello": cmd_hello,
"weather": cmd_weather,
"sysinfo": cmd_sysinfo
}
```
All three commands use argument lists exactly as ZDTT passes them.
---
# 🟫 Installing Plugins
### **Manual Install**
Place plugin file in:
```
~/.zdtt/plugins/
```
Then reload:
```
plugins reload
```
---
### **Install via ZPS**
Install directly from a URL:
```
zps install https://raw.githubusercontent.com/user/repo/plugin.py
```
ZPS will:
* Download the file
* Save it to your plugin directory
* Warn if it already exists
* Ask if you trust imports (if any)
---
# 🟨 Debugging Plugins
ZDTT logs plugin errors to:
```
~/.zdtt/plugin_errors.log
```
Quarantined plugins appear in:
```
~/.zdtt/quarantine/
```
Reload plugins:
```
plugins reload
```
---
# 🟩 Best Practices for Plugin Developers
✔ Wrap all code inside functions
✔ Avoid imports unless required
✔ Validate arg lists
✔ Use try/except around risky operations
✔ Keep commands short and simple
✔ Document your commands
✔ Never modify global state
✔ Dont override protected commands
---
# 🟦 Advanced Plugin Tips
### Show usage/help
```python
def cmd_calc(args):
"""Usage: calc <expression>"""
...
```
ZDTT automatically pulls these docstrings into the `help` system.
### Combine args into a string
```python
expr = " ".join(args)
```
### Use subprocess safely
```python
try:
subprocess.run(["ls"])
except Exception as e:
print("Error:", e)
```
### Read files safely
Use try/except to avoid crashing the shell.
---
# 🟣 Full Plugin Template
```python
"""
Plugin Name: <your plugin>
Description: <what it does>
Author: <you>
"""
# Optional imports (will require trust prompt)
import subprocess
def cmd_example(args):
print("Example plugin working!")
def register_commands():
return {
"example": cmd_example
}
```

268
README.md
View File

@@ -1,6 +1,266 @@
# ZDTT
My lil terminal project
<img src="https://zdtt.zane.org/zdtt.png" width=100>
The terminal is designed only for debian based (arch linux support in testing) linux. It can be installed on nondebian distros but it is not reccomended and may cause issues.
# ZDTT Terminal
*ps: partly vibe coded*
A Python-based, Linux-first custom shell environment with plugin support, aliases, banners, and a modern command experience.
ZDTT wraps your system shell, adds its own built-in commands, and enhances your workflow instead of replacing your OS shell.
---
## ✨ Features
### ✔ Command History
Up/Down arrows navigate session history using Pythons `readline` module.
### ✔ Tab Completion
Auto-complete commands and filesystem paths.
### ✔ Colorized Prompt
ZDTT provides a custom prompt with color styling.
On Linux: supports full status bar.
On macOS: status bar disabled automatically due to OS cursor fight.
### ✔ Plugin System
Python-based plugin loader with AST security checks.
Plugins can register new ZDTT commands without modifying core files.
### ✔ Custom Aliases
Aliases are loaded from `~/.zdtt/aliases` and behave identically to shell shortcuts.
### ✔ Custom Banner Support
If `~/.zdtt/banner.txt` exists, it is displayed on launch.
### ✔ Distro Detection
ZDTT detects which major family youre on:
- Debian-based
- Arch-based
- macOS
Used to determine:
- the correct sysfetch tool
- correct default package manager names
- correct onboarding messages
### ✔ Native Shell Command Relay
If a command is not a built-in ZDTT command or plugin command, it is passed directly to your real shell (bash, zsh, etc.).
### ✔ Status Bar (Linux only)
A background thread draws a live status bar showing time and system state.
Disabled automatically on macOS.
### ✔ Built-in Commands
* `help`
* `clear`
* `about`
* `history`
* `exit`
* `quit`
* `sysfetch`
* `time`
* `statusbar color <name>`
* plus plugin commands
---
## 🎨 Images
<img src="https://zdtt.zane.org/image.png">
---
## 🚀 Installation
### Quick Install
```bash
curl -O https://zdtt-sources.zane.org/install.sh && chmod +x install.sh && ./install.sh
```
The installer:
* Detects Debian, Arch, or macOS
* Installs Python 3 if needed
* Installs ZDTT to ~/.local/bin
* Sets up the `zdtt` command
### Manual Install
```bash
git clone https://github.com/ZaneThePython/ZDTT
cd ZDTT
chmod +x install.sh
./install.sh
```
---
## 📖 Usage
### Start ZDTT
```bash
zdtt start
```
### Management Commands
```bash
zdtt update
zdtt version
zdtt github
zdtt uninstall
```
---
## 🔌 Plugin System
ZDTT supports simple Python plugins stored in:
```
~/.zdtt/plugins/
```
Each plugin must define:
```python
def register_commands():
return {"yourcmd": your_function}
```
Plugins are sandboxed using AST:
* No top-level execution allowed
* Only imports, functions, classes permitted
* Unsafe plugins are quarantined automatically
Reload plugins inside ZDTT:
```
plugins reload
```
Install via URL:
```
zps install <url>
```
See:
* `example_plugin.py`
* `PLUGINS.md`
---
## ⚙ Configuration
### Aliases
Store aliases in:
```
~/.zdtt/aliases
```
Or create them live:
```
alias ll=ls -la
unalias ll
```
### Banner
Add a custom banner in:
```
~/.zdtt/banner.txt
```
### Status Bar Color
```
statusbar color blue
```
Colors supported:
`blue red green cyan magenta yellow white black`
---
## 🖥 Supported Systems
### ✔ Full Support
* Debian-based distros
* Arch-based distros
* macOS (Status bar disabled automatically)
### ⚠ Limited Support
Other distros can run ZDTT but:
* auto-install may not work
* sysfetch may not detect tools
* package-manager messages may be incorrect
---
## 🛠 Development
ZDTT is written in Python and uses:
* `readline` for history & completion
* `threading` for status bar updates
* `ast` for plugin security
* `subprocess` for system command execution
* `os` and `shutil` for path and environment detection
### Project Structure
```
ZDTT/
├── terminal.py
├── install.sh
├── version.txt
├── example_plugin.py
├── example_aliases
├── example_banner.txt
├── PLUGINS.md
└── README.md
```
---
## 🤝 Contributing
PRs welcome!
ZDTT is early in development and evolving quickly.
---
## 🔗 Links
* GitHub: [https://github.com/ZaneThePython/ZDTT](https://github.com/ZaneThePython/ZDTT)
* Main site: [https://zdtt.zane.org](https://zdtt.zane.org)
---
## 💬 Notes
ZDTT is not a full standalone shell *yet* — it wraps your system shell and enhances it.
A full independent shell may come in the future.
Plugins may import Python modules, but may not execute code at import time.
---

Binary file not shown.

BIN
image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZDTT Terminal</title>
<link rel="icon" type="image/png" href="zdtt.png">
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@@ -12,7 +13,7 @@
<body>
<header class="hero" id="top">
<nav class="nav">
<div class="brand">ZDTT</div>
<div class="brand">By ZaneDev</div>
<button class="nav__toggle" type="button" aria-label="Toggle navigation" aria-expanded="false" aria-controls="primary-nav">
<span></span>
<span></span>
@@ -45,11 +46,11 @@
<div class="hero__metrics">
<div class="metric">
<p class="metric__label">Current release</p>
<p class="metric__value">v0.1.2.a.2</p>
<p class="metric__value">v0.1.2.b.5</p>
</div>
<div class="metric">
<p class="metric__label">Supported families</p>
<p class="metric__value">Debian · Arch</p>
<p class="metric__value">Debian · Arch · macOS</p>
</div>
<div class="metric">
<p class="metric__label">Extension slots</p>
@@ -68,11 +69,11 @@
<div class="feature-grid">
<article class="card">
<h3>Smart distro detection</h3>
<p>Installer inspects <code>/etc/os-release</code>, package managers, and user overrides to keep Debian and Arch flows tight.</p>
<p>Installer inspects <code>/etc/os-release</code>, package managers, and user overrides to keep Debian, macOS, and Arch flows tight.</p>
</article>
<article class="card">
<h3>Always-on status bar</h3>
<p>Background thread renders a live status bar with branding, time, and color themes you can swap on the fly.</p>
<p>Background thread renders a live status bar with branding, time, and color themes you can swap on the fly. (unavailable on macOS)</p>
</article>
<article class="card">
<h3>Plugin-friendly core</h3>
@@ -90,6 +91,10 @@
<h3>Graceful fallbacks</h3>
<p>Unsupported systems get friendly warnings, opt-in installs, and clear messaging so nothing breaks silently.</p>
</article>
<article class="card">
<h3>Open source</h3>
<p>ZDTT is open source and free to use. You can find the source code on <a href="https://github.com/ZaneThePython/ZDTT">GitHub</a>.</p>
</article>
</div>
</section>
@@ -105,7 +110,7 @@
</li>
<li>
<h3>Follow the prompts</h3>
<p>The script checks your distro, offers overrides, and handles both Debian (<code>apt</code>) and Arch (<code>pacman</code>) flows.</p>
<p>The script checks your distro, offers overrides, and handles both Debian (<code>apt</code>), Arch (<code>pacman</code>), and macOS (<code>brew</code>) flows.</p>
</li>
<li>
<h3>Launch <code>zdtt</code></h3>
@@ -113,7 +118,7 @@
</li>
</ol>
<div class="callout">
<p><strong>Heads up:</strong> ZDTT is Linux-only. Non-Debian/Arch installs can continue at your own risk—warnings are built in.</p>
<p><strong>Heads up:</strong> ZDTT is Linux-only (with eperimental macOS support). Non-Debian/Arch installs can continue at your own risk—warnings are built in.</p>
</div>
</section>
@@ -157,14 +162,15 @@ Traceback (most recent call last):
<p>ZDTT thrives on experimentation. Fork it, vibe with it, file PRs, or just send screenshots.</p>
</div>
<div class="community__actions">
<a class="btn primary" href="mailto:hello@zane.org">Say hello</a>
<a class="btn ghost" href="https://github.com/" target="_blank" rel="noreferrer">View source</a>
<a class="btn primary" href="mailto:contact@zane.org">Contact us if issues arise</a>
<a class="btn ghost" href="https://github.com/ZaneThePython/ZDTT" target="_blank" rel="noreferrer">View source</a>
</div>
</section>
</main>
<footer class="footer">
<p>© <span id="year"></span> ZDTT • Built for Debian + Arch explorers.</p>
<p>© <span id="year"></span> - ZBF LLC</p>
<p>ZDTT - ZaneDev's Terminal Tools</p>
<a href="#top">Back to top ↑</a>
</footer>

View File

@@ -72,10 +72,20 @@ if [ -f "$BIN_DIR/zdtt" ] || [ -d "$INSTALL_DIR" ]; then
esac
fi
# Check if running on macOS
IS_MAC=false
if [[ "$(uname)" == "Darwin" ]]; then
IS_MAC=true
DETECTED_DISTRO="mac"
echo -e "${GREEN}${NC} macOS detected"
fi
# Check if running on a supported Linux distribution
IS_DEBIAN=false
IS_ARCH=false
DETECTED_DISTRO="other"
if [ "$IS_MAC" = false ]; then
DETECTED_DISTRO="other"
fi
OS_ID=""
OS_LIKE=""
@@ -86,7 +96,10 @@ if [ -f /etc/os-release ]; then
OS_LIKE=$(echo "${ID_LIKE:-}" | tr '[:upper:]' '[:lower:]')
fi
if [ -f /etc/debian_version ]; then
if [ "$IS_MAC" = true ]; then
# macOS detected, skip Linux detection
:
elif [ -f /etc/debian_version ]; then
IS_DEBIAN=true
DETECTED_DISTRO="debian"
echo -e "${GREEN}${NC} Debian-based Linux detected"
@@ -133,25 +146,35 @@ else
fi
echo "Detected distribution: ${DETECTED_DISTRO}"
read -p "Override detection? (debian/arch/other, Enter to keep): " -r USER_OVERRIDE
read -p "Override detection? (debian/arch/mac/other, Enter to keep): " -r USER_OVERRIDE
USER_OVERRIDE=$(echo "$USER_OVERRIDE" | tr '[:upper:]' '[:lower:]')
case "$USER_OVERRIDE" in
debian)
IS_DEBIAN=true
IS_ARCH=false
IS_MAC=false
DETECTED_DISTRO="debian"
echo "Override applied: Debian-based system selected."
;;
arch)
IS_DEBIAN=false
IS_ARCH=true
IS_MAC=false
DETECTED_DISTRO="arch"
echo "Override applied: Arch-based system selected."
;;
mac)
IS_DEBIAN=false
IS_ARCH=false
IS_MAC=true
DETECTED_DISTRO="mac"
echo "Override applied: macOS selected."
;;
other)
IS_DEBIAN=false
IS_ARCH=false
IS_MAC=false
DETECTED_DISTRO="other"
echo "Override applied: Unsupported/Other selected."
;;
@@ -168,7 +191,90 @@ if ! command -v python3 &> /dev/null; then
echo -e "${RED}${NC} Python 3 is not installed"
echo ""
if [ "$IS_DEBIAN" = true ]; then
if [ "$IS_MAC" = true ]; then
echo "Checking for Homebrew..."
BREW_PATH=""
if command -v brew &> /dev/null; then
BREW_PATH="brew"
elif [ -f "/opt/homebrew/bin/brew" ]; then
BREW_PATH="/opt/homebrew/bin/brew"
elif [ -f "/usr/local/bin/brew" ]; then
BREW_PATH="/usr/local/bin/brew"
fi
if [ -n "$BREW_PATH" ]; then
echo "Installing Python 3 via Homebrew..."
$BREW_PATH install python3
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to install Python 3${NC}"
echo "Please install Python 3 manually: $BREW_PATH install python3"
echo ""
echo "Press any key to exit..."
read -n 1 -s -r
exit 1
fi
echo -e "${GREEN}${NC} Python 3 installed successfully"
else
echo -e "${RED}Homebrew is not installed.${NC}"
echo ""
echo "Homebrew is required for package management on macOS."
echo ""
read -p "Would you like to install Homebrew now? (yes/no): " -r
echo ""
if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
echo "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
if [ $? -eq 0 ]; then
echo -e "${GREEN}${NC} Homebrew installed successfully"
echo ""
echo "Adding Homebrew to PATH..."
# Add Homebrew to PATH for this session
if [ -d "/opt/homebrew/bin" ]; then
export PATH="/opt/homebrew/bin:$PATH"
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -d "/usr/local/bin" ]; then
export PATH="/usr/local/bin:$PATH"
eval "$(/usr/local/bin/brew shellenv)"
fi
echo ""
echo "Installing Python 3..."
brew install python3
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to install Python 3${NC}"
echo "Please install Python 3 manually: brew install python3"
echo ""
echo "Press any key to exit..."
read -n 1 -s -r
exit 1
fi
echo -e "${GREEN}${NC} Python 3 installed successfully"
else
echo -e "${RED}Failed to install Homebrew${NC}"
echo "Please install Homebrew manually:"
echo " /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
echo ""
echo "Press any key to exit..."
read -n 1 -s -r
exit 1
fi
else
echo -e "${RED}Python 3 is required but cannot be installed without Homebrew.${NC}"
echo ""
echo "Please install Homebrew and Python 3 manually:"
echo " /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
echo " brew install python3"
echo ""
echo "Press any key to exit..."
read -n 1 -s -r
exit 1
fi
fi
elif [ "$IS_DEBIAN" = true ]; then
echo "Installing Python 3..."
# Update package list and install Python 3
@@ -207,6 +313,7 @@ if ! command -v python3 &> /dev/null; then
echo "Please install Python 3 manually using your package manager:"
echo " • Debian/Ubuntu: sudo apt-get install python3"
echo " • Arch/Manjaro: sudo pacman -S python"
echo " • macOS: brew install python3"
echo " • Fedora: sudo dnf install python3"
echo " • openSUSE: sudo zypper install python3"
echo ""
@@ -321,9 +428,10 @@ fi
# Create the zdtt wrapper script
cat > "$BIN_DIR/zdtt" << 'EOF'
#!/bin/bash
#!/usr/bin/env bash
#
# ZDTT Terminal Wrapper
# Compatible with both bash and zsh
#
ZDTT_DIR="$HOME/.local/share/zdtt"
@@ -335,6 +443,12 @@ case "$1" in
python3 "$ZDTT_DIR/terminal.py"
;;
update)
# Check for auto-update flag
AUTO_UPDATE=false
if [[ "$2" == "--auto" ]] || [[ "$2" == "--yes" ]]; then
AUTO_UPDATE=true
fi
echo "Checking for updates..."
echo ""
@@ -369,8 +483,16 @@ case "$1" in
else
echo "🔔 Update available!"
echo ""
read -p "Do you want to update now? (yes/no): " -r
echo ""
# Auto-update if flag is set, otherwise prompt
if [ "$AUTO_UPDATE" = true ]; then
REPLY="yes"
echo "Auto-updating..."
echo ""
else
read -p "Do you want to update now? (yes/no): " -r
echo ""
fi
if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
echo "Updating ZDTT Terminal..."
@@ -461,6 +583,29 @@ case "$1" in
echo " • Plugin system"
echo " • Native command support"
;;
github)
GITHUB_URL="https://github.com/ZaneThePython/ZDTT"
echo "Opening ZDTT GitHub repository..."
# Detect platform and use appropriate command to open URL
if [[ "$(uname)" == "Darwin" ]]; then
# macOS
open "$GITHUB_URL"
elif command -v xdg-open &> /dev/null; then
# Linux (most distributions)
xdg-open "$GITHUB_URL"
elif command -v x-www-browser &> /dev/null; then
# Linux (Debian/Ubuntu fallback)
x-www-browser "$GITHUB_URL"
elif command -v gnome-open &> /dev/null; then
# Linux (GNOME fallback)
gnome-open "$GITHUB_URL"
else
# Fallback: print URL and let user open manually
echo "Please open this URL in your browser:"
echo "$GITHUB_URL"
fi
;;
*)
echo "ZDTT Terminal"
echo ""
@@ -469,6 +614,7 @@ case "$1" in
echo " zdtt update - Check for and install updates"
echo " zdtt installer - Run installer (for updates/reinstall)"
echo " zdtt version - Display version information"
echo " zdtt github - Open ZDTT GitHub repository"
echo " zdtt uninstall - Uninstall ZDTT Terminal"
echo ""
;;
@@ -484,22 +630,81 @@ if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
echo ""
echo -e "${YELLOW}Warning: $HOME/.local/bin is not in your PATH${NC}"
echo ""
echo "To use the 'zdtt' command, add the following line to your ~/.bashrc:"
# Detect user's default shell (not the script's shell)
# Priority: 1) Check if running in zsh, 2) Check if .zshrc exists, 3) Check $SHELL, 4) Check /etc/passwd, 5) Default to bash
SHELL_CONFIG="$HOME/.bashrc"
SHELL_NAME="bash"
# Check if running in zsh (most reliable - immediate detection)
if [[ -n "$ZSH_VERSION" ]]; then
SHELL_CONFIG="$HOME/.zshrc"
SHELL_NAME="zsh"
# Check if .zshrc exists (strong indicator user uses zsh)
elif [ -f "$HOME/.zshrc" ]; then
SHELL_CONFIG="$HOME/.zshrc"
SHELL_NAME="zsh"
# Check $SHELL environment variable
elif [[ -n "$SHELL" ]] && [[ "$SHELL" == *"zsh"* ]]; then
SHELL_CONFIG="$HOME/.zshrc"
SHELL_NAME="zsh"
# Check user's default shell from /etc/passwd
else
USER_SHELL=""
if command -v getent &> /dev/null; then
USER_SHELL=$(getent passwd "$USER" 2>/dev/null | cut -d: -f7)
elif [ -f /etc/passwd ]; then
USER_SHELL=$(grep "^$USER:" /etc/passwd 2>/dev/null | cut -d: -f7)
fi
if [[ -n "$USER_SHELL" ]] && [[ "$USER_SHELL" == *"zsh"* ]]; then
SHELL_CONFIG="$HOME/.zshrc"
SHELL_NAME="zsh"
fi
fi
echo -e "${GREEN}Detected shell: ${SHELL_NAME}${NC}"
echo -e "Config file: ${SHELL_CONFIG}"
echo ""
echo "To use the 'zdtt' command, add the following line to your $SHELL_CONFIG:"
echo ""
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
echo ""
echo "Then run: source ~/.bashrc"
echo "Then run: source $SHELL_CONFIG"
echo ""
# Ask if user wants to add it automatically
read -p "Would you like to add it to your ~/.bashrc now? (y/n) " -n 1 -r
read -p "Would you like to add it to your $SHELL_CONFIG now? (y/n) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "" >> "$HOME/.bashrc"
echo "# Added by ZDTT Terminal installer" >> "$HOME/.bashrc"
echo "export PATH=\"\$HOME/.local/bin:\$PATH\"" >> "$HOME/.bashrc"
echo -e "${GREEN}${NC} Added to ~/.bashrc"
echo "Please run: source ~/.bashrc"
# Create the config file if it doesn't exist
if [ ! -f "$SHELL_CONFIG" ]; then
touch "$SHELL_CONFIG"
fi
# Check if the PATH line already exists (check for various formats)
PATH_ALREADY_SET=false
if grep -q '\.local/bin' "$SHELL_CONFIG" 2>/dev/null; then
PATH_ALREADY_SET=true
fi
if [ "$PATH_ALREADY_SET" = false ]; then
echo "" >> "$SHELL_CONFIG"
echo "# Added by ZDTT Terminal installer" >> "$SHELL_CONFIG"
echo "export PATH=\"\$HOME/.local/bin:\$PATH\"" >> "$SHELL_CONFIG"
echo -e "${GREEN}${NC} Added to $SHELL_CONFIG"
echo ""
echo "To apply the changes, run:"
echo " source $SHELL_CONFIG"
echo ""
echo "Or open a new terminal window."
else
echo -e "${GREEN}${NC} PATH already configured in $SHELL_CONFIG"
echo ""
echo "If 'zdtt' command is not available, run:"
echo " source $SHELL_CONFIG"
echo ""
fi
fi
else
echo -e "${GREEN}${NC} ~/.local/bin is already in your PATH"
@@ -515,3 +720,4 @@ echo " zdtt start"
echo ""
echo "Press any key to exit..."
read -n 1 -s -r

View File

@@ -72,4 +72,46 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
});
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
const href = this.getAttribute('href');
if (href === '#' || href === '#top') return;
e.preventDefault();
const target = document.querySelector(href);
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Intersection Observer for fade-in animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// Observe sections and cards for fade-in effect (exclude hero section)
const animatedElements = document.querySelectorAll('.section:not(.hero), .card, .metric, figure, .install-steps li');
animatedElements.forEach(el => {
el.style.opacity = '0';
el.style.transform = 'translateY(20px)';
el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
observer.observe(el);
});
});

View File

@@ -4,12 +4,14 @@
--bg: #05060a;
--bg-alt: #0e1018;
--card: #121422;
--card-border: rgba(255, 255, 255, 0.08);
--card-border: rgba(255, 255, 255, 0.12);
--text: #f5f6fd;
--muted: #9aa2c4;
--accent: #4dd5ff;
--accent-strong: #6d84ff;
--accent-glow: rgba(77, 213, 255, 0.4);
--shadow: 0 18px 45px rgba(4, 6, 11, 0.6);
--shadow-glow: 0 0 30px rgba(77, 213, 255, 0.2);
}
*,
@@ -18,15 +20,43 @@
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
min-height: 100vh;
background: radial-gradient(circle at top, rgba(77, 213, 255, 0.12), transparent 55%),
radial-gradient(circle at 20% 20%, rgba(109, 132, 255, 0.25), transparent 35%),
var(--bg);
background:
radial-gradient(circle at 0% 0%, rgba(77, 213, 255, 0.15), transparent 50%),
radial-gradient(circle at 100% 0%, rgba(109, 132, 255, 0.2), transparent 50%),
radial-gradient(circle at 50% 100%, rgba(77, 213, 255, 0.08), transparent 60%),
var(--bg);
background-attachment: fixed;
color: var(--text);
font-size: 1rem;
line-height: 1.6;
position: relative;
overflow-x: hidden;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 30%, rgba(77, 213, 255, 0.03), transparent 50%),
radial-gradient(circle at 80% 70%, rgba(109, 132, 255, 0.03), transparent 50%);
pointer-events: none;
z-index: 0;
}
body > * {
position: relative;
z-index: 1;
}
img {
@@ -56,6 +86,27 @@ button:focus-visible {
display: flex;
flex-direction: column;
gap: 2rem;
position: relative;
overflow: hidden;
}
.hero::after {
content: '';
position: absolute;
top: -50%;
right: -20%;
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(77, 213, 255, 0.1), transparent 70%);
border-radius: 50%;
filter: blur(60px);
pointer-events: none;
animation: pulse 8s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1) translate(0, 0); opacity: 0.6; }
50% { transform: scale(1.2) translate(-10%, 10%); opacity: 0.8; }
}
.nav {
@@ -68,6 +119,12 @@ button:focus-visible {
.brand {
font-weight: 700;
letter-spacing: 0.08em;
font-size: 1.25rem;
background: linear-gradient(135deg, var(--accent), var(--accent-strong));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 0 20px var(--accent-glow);
}
.nav__links {
@@ -79,14 +136,32 @@ button:focus-visible {
.nav__links a {
color: var(--muted);
font-weight: 500;
transition: color 0.2s ease;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
text-decoration: none;
position: relative;
padding: 0.5rem 0;
}
.nav__links a::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: linear-gradient(90deg, var(--accent), var(--accent-strong));
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 0 10px var(--accent-glow);
}
.nav__links a:hover {
color: var(--text);
}
.nav__links a:hover::after {
width: 100%;
}
.nav__toggle {
display: none;
background: none;
@@ -119,6 +194,11 @@ h1 {
font-size: clamp(2.7rem, 5vw, 4.8rem);
margin: 0 0 1rem;
line-height: 1.05;
background: linear-gradient(135deg, var(--text) 0%, var(--accent) 50%, var(--accent-strong) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
filter: drop-shadow(0 0 20px rgba(77, 213, 255, 0.3));
}
h2 {
@@ -149,8 +229,28 @@ h3 {
border-radius: 999px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
text-decoration: none;
position: relative;
overflow: hidden;
}
.btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.btn:hover::before {
width: 300px;
height: 300px;
}
.btn:focus-visible {
@@ -163,32 +263,51 @@ h3 {
}
.btn.primary {
background: linear-gradient(90deg, var(--accent-strong), var(--accent));
background: linear-gradient(135deg, var(--accent-strong), var(--accent));
color: #05060a;
border: none;
box-shadow: 0 15px 40px rgba(77, 213, 255, 0.3);
box-shadow: 0 15px 40px rgba(77, 213, 255, 0.3), 0 0 20px rgba(77, 213, 255, 0.2);
z-index: 1;
}
.btn.primary:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 20px 50px rgba(77, 213, 255, 0.4), 0 0 30px rgba(77, 213, 255, 0.3);
}
.btn.ghost {
border-color: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.25);
color: var(--text);
background: transparent;
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(10px);
z-index: 1;
}
.btn:hover {
transform: translateY(-1px);
box-shadow: 0 12px 30px rgba(109, 132, 255, 0.25);
.btn.ghost:hover {
transform: translateY(-2px);
border-color: rgba(77, 213, 255, 0.5);
background: rgba(77, 213, 255, 0.1);
box-shadow: 0 10px 30px rgba(77, 213, 255, 0.15);
}
.install-command {
display: block;
padding: 1rem 1.25rem;
border-radius: 0.75rem;
background: rgba(18, 20, 34, 0.7);
background: rgba(18, 20, 34, 0.8);
border: 1px solid var(--card-border);
font-family: 'JetBrains Mono', 'Space Grotesk', monospace;
font-size: 0.95rem;
overflow-x: auto;
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
position: relative;
}
.install-command:hover {
border-color: rgba(77, 213, 255, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), 0 0 20px rgba(77, 213, 255, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
.hero__metrics {
@@ -201,7 +320,32 @@ h3 {
padding: 1.25rem;
border-radius: 1rem;
border: 1px solid var(--card-border);
background: rgba(5, 6, 10, 0.55);
background: rgba(5, 6, 10, 0.6);
backdrop-filter: blur(10px);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.metric::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(77, 213, 255, 0.1), transparent);
transition: left 0.5s ease;
}
.metric:hover {
transform: translateY(-4px);
border-color: rgba(77, 213, 255, 0.3);
box-shadow: 0 10px 30px rgba(77, 213, 255, 0.15);
}
.metric:hover::before {
left: 100%;
}
.metric__label {
@@ -239,6 +383,40 @@ h3 {
background: var(--card);
box-shadow: var(--shadow);
min-height: 10rem;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
backdrop-filter: blur(10px);
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--accent), transparent);
transform: translateX(-100%);
transition: transform 0.6s ease;
}
.card:hover {
transform: translateY(-6px);
border-color: rgba(77, 213, 255, 0.4);
box-shadow: 0 20px 50px rgba(77, 213, 255, 0.2), var(--shadow);
}
.card:hover::before {
transform: translateX(100%);
}
.card h3 {
transition: color 0.3s ease;
}
.card:hover h3 {
color: var(--accent);
}
.card p {
@@ -262,10 +440,19 @@ h3 {
padding: 1.5rem;
border-radius: 1rem;
border: 1px solid var(--card-border);
background: rgba(5, 6, 10, 0.5);
background: rgba(5, 6, 10, 0.6);
backdrop-filter: blur(10px);
counter-increment: install-step;
position: relative;
padding-left: 4.5rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.install-steps li:hover {
transform: translateX(8px);
border-color: rgba(77, 213, 255, 0.3);
background: rgba(5, 6, 10, 0.7);
box-shadow: 0 10px 30px rgba(77, 213, 255, 0.1);
}
.install-steps li::before {
@@ -281,6 +468,14 @@ h3 {
display: grid;
place-items: center;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: 0 0 15px rgba(77, 213, 255, 0.3);
}
.install-steps li:hover::before {
background: rgba(77, 213, 255, 0.3);
box-shadow: 0 0 25px rgba(77, 213, 255, 0.5);
transform: scale(1.1);
}
.callout {
@@ -289,6 +484,14 @@ h3 {
border-radius: 1rem;
background: rgba(255, 196, 87, 0.12);
border: 1px solid rgba(255, 196, 87, 0.35);
backdrop-filter: blur(10px);
box-shadow: 0 8px 32px rgba(255, 196, 87, 0.1);
transition: all 0.3s ease;
}
.callout:hover {
border-color: rgba(255, 196, 87, 0.5);
box-shadow: 0 8px 32px rgba(255, 196, 87, 0.2);
}
.showcase__grid {
@@ -303,7 +506,33 @@ figure {
border-radius: 1rem;
padding: 1rem;
background: rgba(9, 10, 18, 0.8);
backdrop-filter: blur(10px);
min-height: 15rem;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
figure::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(77, 213, 255, 0.1), transparent 70%);
opacity: 0;
transition: opacity 0.4s ease;
}
figure:hover {
transform: translateY(-8px) scale(1.02);
border-color: rgba(77, 213, 255, 0.4);
box-shadow: 0 20px 50px rgba(77, 213, 255, 0.2);
}
figure:hover::before {
opacity: 1;
}
figcaption {
@@ -313,22 +542,55 @@ figcaption {
}
pre {
background: rgba(5, 6, 10, 0.65);
background: rgba(5, 6, 10, 0.8);
padding: 1rem;
border-radius: 0.75rem;
overflow: auto;
font-size: 0.85rem;
line-height: 1.3;
border: 1px solid rgba(77, 213, 255, 0.1);
box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.3);
position: relative;
backdrop-filter: blur(5px);
}
pre::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(77, 213, 255, 0.3), transparent);
}
.statusbar-demo {
display: flex;
justify-content: space-between;
background: linear-gradient(90deg, var(--accent-strong), var(--accent));
background: linear-gradient(135deg, var(--accent-strong), var(--accent));
color: #05060a;
padding: 0.65rem 1rem;
border-radius: 0.5rem;
font-weight: 600;
box-shadow: 0 4px 20px rgba(77, 213, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
position: relative;
overflow: hidden;
}
.statusbar-demo::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
animation: shimmer 3s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
.community__actions {
@@ -340,7 +602,7 @@ pre {
.footer {
padding: 2rem clamp(1.5rem, 5vw, 5rem);
border-top: 1px solid rgba(255, 255, 255, 0.08);
border-top: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
@@ -348,6 +610,28 @@ pre {
gap: 1rem;
font-size: 0.9rem;
color: var(--muted);
background: rgba(5, 6, 10, 0.5);
backdrop-filter: blur(10px);
position: relative;
}
.footer::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(77, 213, 255, 0.3), transparent);
}
.footer a {
transition: all 0.3s ease;
}
.footer a:hover {
color: var(--accent);
text-shadow: 0 0 10px var(--accent-glow);
}
@media (max-width: 720px) {
@@ -365,9 +649,27 @@ pre {
flex-direction: column;
padding: 1rem 0 0;
gap: 0.75rem;
background: rgba(5, 6, 10, 0.95);
backdrop-filter: blur(20px);
border-radius: 0.5rem;
padding: 1rem;
margin-top: 1rem;
border: 1px solid var(--card-border);
}
.nav__links.is-open {
display: flex;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
0.1.2.a.2
0.1.2.b.5

BIN
zdtt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB