feat: docus

This commit is contained in:
2025-10-08 13:54:19 +02:00
parent 47539d8cc8
commit 223cc2ac6a
31 changed files with 2476 additions and 1820 deletions

27
Projects/kompose/docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,27 @@
# Nuxt
.nuxt
.output
.env
dist
# Node
node_modules
*.log*
.DS_Store
.vscode
.idea
# Build
.output
.nuxt
# Cache
.cache
# Temp
*.tmp
*.bak
*.swp
# pnpm
pnpm-lock.yaml

View File

@@ -0,0 +1,36 @@
# Build stage
FROM node:20-alpine AS builder
# Install pnpm
RUN npm install -g pnpm@9.0.0
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml* ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source code
COPY . .
# Generate static site
RUN pnpm run generate
# Production stage
FROM nginx:alpine
# Copy custom nginx config
COPY nginx.conf /etc/nginx/nginx.conf
# Copy built static site
COPY --from=builder /app/.output/public /usr/share/nginx/html
# Add healthcheck
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:80/ || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,257 @@
# Kompose Documentation
Modern, stylish documentation site for Kompose built with Nuxt Content and featuring a funky dark theme with orange and purple gradients.
## 🎨 Features
-**Modern Dark Theme** - Funky design with orange and purple gradients
- 📝 **Markdown Support** - Write documentation in Markdown
- 🔍 **Full-Text Search** - Search through all documentation
- 📱 **Responsive Design** - Works perfectly on all devices
- 🎯 **Table of Contents** - Auto-generated navigation
- 🎨 **Syntax Highlighting** - Beautiful code blocks with multiple language support
- 🚀 **Static Generation** - Fast, SEO-friendly static site
- 📊 **PWA Ready** - Progressive Web App capabilities
## 🚀 Quick Start
### Development
```bash
# Install dependencies
pnpm install
# Start development server
pnpm run dev
# Open http://localhost:3000
```
### Production Build
```bash
# Generate static site
pnpm run generate
# Preview production build
pnpm run preview
```
### Docker Deployment
```bash
# Build and start the docs container
cd /path/to/kompose
./kompose.sh docs up -d --build
# View logs
./kompose.sh docs logs -f
```
## 📁 Project Structure
```
docs/
├── assets/ # Static assets and global CSS
│ └── css/
│ └── main.css # Custom Tailwind styles
├── components/ # Vue components
├── content/ # Markdown documentation
│ └── docs/ # Documentation pages
│ └── index.md
├── layouts/ # Page layouts
│ └── default.vue # Main layout with sidebar
├── pages/ # Application pages
│ ├── index.vue # Homepage
│ └── docs/
│ └── [...slug].vue # Documentation pages
├── public/ # Static files
├── app.vue # App entry point
├── nuxt.config.ts # Nuxt configuration
├── tailwind.config.js # Tailwind configuration
├── package.json # Dependencies
├── Dockerfile # Docker build configuration
├── nginx.conf # Nginx configuration
└── compose.yaml # Docker Compose configuration
```
## 📝 Writing Documentation
Documentation files are stored in `content/docs/` directory as Markdown files.
### Creating a New Page
1. Create a new `.md` file in `content/docs/`:
```markdown
---
title: Your Page Title
description: Brief description of the page
---
# Your Page Title
Your content goes here...
```
2. The page will be automatically available at `/docs/your-file-name`
### Frontmatter Options
```yaml
---
title: Page Title # Required: Page title
description: Description # Optional: Meta description
---
```
### Markdown Features
#### Code Blocks
\`\`\`bash
./kompose.sh "*" up -d
\`\`\`
#### Alerts
> 💡 **Tip:** This is a helpful tip!
#### Tables
| Column 1 | Column 2 |
|----------|----------|
| Value 1 | Value 2 |
#### Links
[Link Text](/docs/page)
## 🎨 Customizing the Theme
### Colors
Edit `tailwind.config.js` to customize colors:
```js
theme: {
extend: {
colors: {
primary: {
500: '#f97316', // Orange
// ... other shades
},
accent: {
500: '#a855f7', // Purple
// ... other shades
}
}
}
}
```
### Styles
Global styles are in `assets/css/main.css`. You can modify:
- Gradient effects
- Typography
- Component styles
- Animations
## 🔍 Search Configuration
Search is powered by Nuxt Content's built-in search. To customize:
```ts
// nuxt.config.ts
content: {
experimental: {
search: {
indexed: true,
// Add search configuration
}
}
}
```
## 🌐 Deployment
The site is automatically built and deployed via Docker when using Kompose:
```bash
# Rebuild and redeploy
./kompose.sh docs down
./kompose.sh docs up -d --build
```
### Environment Variables
Configure in `docs/.env`:
```env
COMPOSE_PROJECT_NAME=docs
TRAEFIK_HOST=docs.example.com
APP_PORT=80
```
## 📦 Dependencies
- **Nuxt 3** - Vue framework
- **Nuxt Content** - File-based CMS
- **Tailwind CSS** - Utility-first CSS framework
- **@nuxt/icon** - Icon component
- **@vueuse/nuxt** - Vue composition utilities
## 🛠️ Development Tips
### Hot Reload
The development server supports hot module replacement. Changes to components, pages, and markdown files will be reflected immediately.
### TypeScript
The project uses TypeScript. Type definitions are automatically generated by Nuxt.
### Adding Components
Create components in `components/` directory. They'll be auto-imported:
```vue
<!-- components/MyComponent.vue -->
<template>
<div>My Component</div>
</template>
```
Use in pages:
```vue
<template>
<MyComponent />
</template>
```
## 🎯 Features Roadmap
- [ ] Advanced search with filters
- [ ] Dark/light mode toggle
- [ ] API documentation generator
- [ ] Interactive code examples
- [ ] Version selector
- [ ] Multi-language support
## 📄 License
MIT License - see the main Kompose repository for details.
## 🤝 Contributing
1. Fork the repository
2. Create your feature branch: `git checkout -b feature/amazing-feature`
3. Commit your changes: `git commit -m 'Add amazing feature'`
4. Push to the branch: `git push origin feature/amazing-feature`
5. Open a Pull Request
---
Made with ❤️ and ☕ by the Kompose Community

View File

@@ -0,0 +1,46 @@
<template>
<div class="min-h-screen bg-dark-950 text-gray-100">
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
<script setup>
useHead({
htmlAttrs: {
class: 'dark'
}
})
</script>
<style>
@import '@/assets/css/main.css';
/* Custom scrollbar */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
@apply bg-dark-900;
}
::-webkit-scrollbar-thumb {
@apply bg-gradient-to-b from-primary-500 to-accent-500 rounded-full;
}
::-webkit-scrollbar-thumb:hover {
@apply from-primary-400 to-accent-400;
}
/* Selection */
::selection {
@apply bg-primary-500/30 text-white;
}
::-moz-selection {
@apply bg-primary-500/30 text-white;
}
</style>

View File

@@ -0,0 +1,214 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
@apply scroll-smooth;
}
body {
@apply bg-dark-950 text-gray-100 antialiased;
}
/* Typography improvements */
h1, h2, h3, h4, h5, h6 {
@apply font-bold tracking-tight;
}
h1 {
@apply text-5xl md:text-6xl lg:text-7xl;
}
h2 {
@apply text-4xl md:text-5xl;
}
h3 {
@apply text-3xl md:text-4xl;
}
}
@layer components {
/* Gradient text */
.gradient-text {
@apply bg-gradient-to-r from-primary-400 via-accent-400 to-primary-500 bg-clip-text text-transparent;
}
.gradient-text-hero {
@apply bg-gradient-hero bg-clip-text text-transparent animate-gradient-xy;
}
/* Glass morphism */
.glass {
@apply backdrop-blur-lg bg-white/5 border border-white/10;
}
.glass-dark {
@apply backdrop-blur-lg bg-black/30 border border-white/5;
}
/* Glow effects */
.glow-box {
@apply shadow-glow-cyber;
}
.glow-text {
@apply animate-glow;
}
/* Button styles */
.btn {
@apply px-6 py-3 rounded-lg font-semibold transition-all duration-300 transform hover:scale-105 active:scale-95;
}
.btn-primary {
@apply btn bg-gradient-primary text-white shadow-glow-orange hover:shadow-lg;
}
.btn-accent {
@apply btn bg-gradient-accent text-white shadow-glow-purple hover:shadow-lg;
}
.btn-ghost {
@apply btn border-2 border-primary-500/50 text-primary-400 hover:bg-primary-500/10 hover:border-primary-400;
}
/* Card styles */
.card {
@apply rounded-xl p-6 transition-all duration-300;
}
.card-glass {
@apply card glass hover:bg-white/10;
}
.card-glow {
@apply card bg-dark-900 border border-primary-500/20 hover:border-primary-500/40 hover:shadow-glow-cyber;
}
/* Code block improvements */
.prose pre {
@apply relative overflow-hidden;
}
.prose pre::before {
content: '';
@apply absolute inset-0 bg-gradient-shine opacity-0 hover:opacity-100 transition-opacity duration-500 pointer-events-none;
animation: shimmer 2s linear infinite;
}
/* Link styles */
.link-fancy {
@apply relative inline-block text-primary-400 hover:text-primary-300 transition-colors;
}
.link-fancy::after {
content: '';
@apply absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-primary transition-all duration-300;
}
.link-fancy:hover::after {
@apply w-full;
}
/* Sidebar */
.sidebar-link {
@apply block px-4 py-2 rounded-lg text-gray-400 hover:text-white hover:bg-white/5 transition-all duration-200;
}
.sidebar-link.active {
@apply text-white bg-gradient-to-r from-primary-500/20 to-accent-500/20 border-l-4 border-primary-500;
}
/* Search box */
.search-box {
@apply w-full px-4 py-3 bg-dark-900 border border-dark-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 transition-all;
}
/* Table of contents */
.toc-link {
@apply text-sm text-gray-400 hover:text-primary-400 transition-colors py-1 border-l-2 border-dark-700 pl-4 hover:border-primary-500;
}
.toc-link.active {
@apply text-primary-400 border-primary-500;
}
}
@layer utilities {
/* Gradient animations */
.animate-gradient {
background-size: 200% 200%;
animation: gradient 8s ease infinite;
}
/* Perspective utilities */
.perspective-1000 {
perspective: 1000px;
}
.transform-style-3d {
transform-style: preserve-3d;
}
/* Shimmer effect */
.shimmer {
@apply relative overflow-hidden;
}
.shimmer::after {
content: '';
@apply absolute inset-0 bg-gradient-shine;
animation: shimmer 2s infinite;
}
}
/* Markdown content improvements */
.prose {
@apply max-w-none;
}
.prose img {
@apply rounded-lg shadow-lg;
}
.prose table {
@apply w-full border-collapse;
}
.prose th {
@apply bg-dark-800 text-primary-400 font-semibold py-3 px-4 text-left border-b-2 border-primary-500/30;
}
.prose td {
@apply py-3 px-4 border-b border-dark-700;
}
.prose tr:hover {
@apply bg-white/5;
}
/* Copy button for code blocks */
.copy-button {
@apply absolute top-2 right-2 p-2 rounded-md bg-dark-800 text-gray-400 hover:text-white hover:bg-dark-700 transition-all opacity-0 group-hover:opacity-100;
}
/* Loading states */
.loading-dots {
@apply inline-flex space-x-1;
}
.loading-dots span {
@apply w-2 h-2 bg-primary-500 rounded-full animate-pulse;
animation-delay: calc(var(--i) * 150ms);
}
/* Hero section decorations */
.hero-decoration {
@apply absolute pointer-events-none;
}
.hero-blob {
@apply absolute w-96 h-96 bg-gradient-radial from-primary-500/30 to-transparent rounded-full blur-3xl animate-pulse-slow;
}

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# Build script for Kompose documentation
set -e
echo "🎨 Building Kompose Documentation..."
echo ""
# Check if pnpm is installed
if ! command -v pnpm &> /dev/null; then
echo "❌ pnpm is not installed. Installing pnpm..."
npm install -g pnpm@9.0.0
fi
# Install dependencies
echo "📦 Installing dependencies..."
pnpm install
# Generate static site
echo "🔨 Generating static site..."
pnpm run generate
echo ""
echo "✅ Build complete!"
echo "📁 Output directory: .output/public"
echo ""
echo "To preview locally:"
echo " pnpm run preview"
echo ""
echo "To deploy with Docker:"
echo " ./kompose.sh docs up -d --build"

View File

@@ -0,0 +1,38 @@
<template>
<div class="relative group">
<slot />
<button
@click="copyCode"
class="absolute top-2 right-2 p-2 rounded-md bg-dark-800 text-gray-400 hover:text-white hover:bg-dark-700 transition-all opacity-0 group-hover:opacity-100"
:class="{ '!opacity-100': copied }"
>
<Icon v-if="!copied" name="lucide:copy" class="w-4 h-4" />
<Icon v-else name="lucide:check" class="w-4 h-4 text-green-500" />
</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
code: {
type: String,
required: true
}
})
const copied = ref(false)
const copyCode = async () => {
try {
await navigator.clipboard.writeText(props.code)
copied.value = true
setTimeout(() => {
copied.value = false
}, 2000)
} catch (err) {
console.error('Failed to copy code:', err)
}
}
</script>

View File

@@ -0,0 +1,32 @@
name: docs
services:
docs:
build:
context: .
dockerfile: Dockerfile
container_name: ${COMPOSE_PROJECT_NAME}_app
restart: unless-stopped
volumes:
# Mount the built static site
- ./.output/public:/usr/share/nginx/html:ro
networks:
- kompose_network
labels:
- 'traefik.enable=true'
- 'traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-redirect-web-secure.redirectscheme.scheme=https'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web.middlewares=${COMPOSE_PROJECT_NAME}-redirect-web-secure'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web.rule=Host(`${TRAEFIK_HOST}`)'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web.entrypoints=web'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.rule=Host(`${TRAEFIK_HOST}`)'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.tls.certresolver=resolver'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.entrypoints=web-secure'
- 'traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-web-secure-compress.compress=true'
- 'traefik.http.routers.${COMPOSE_PROJECT_NAME}-web-secure.middlewares=${COMPOSE_PROJECT_NAME}-web-secure-compress'
- 'traefik.http.services.${COMPOSE_PROJECT_NAME}-web-secure.loadbalancer.server.port=80'
- 'traefik.docker.network=${NETWORK_NAME:-kompose}'
networks:
kompose_network:
name: ${NETWORK_NAME:-kompose}
external: true

View File

@@ -0,0 +1,65 @@
---
title: Introduction to Kompose
description: Learn about Kompose, your Docker Compose Symphony Conductor for managing multiple stacks with style and grace.
---
# Introduction to Kompose
**Kompose** is a powerful Bash orchestration tool for managing multiple Docker Compose stacks with style and grace. Think of it as a conductor for your Docker symphony - each stack plays its part, and Kompose makes sure they're all in harmony.
## Why Kompose?
🎯 **One Command to Rule Them All** - Manage dozens of stacks with a single command
🔄 **Database Wizardry** - Export, import, and clean up PostgreSQL databases like a boss
🎪 **Hook System** - Extend functionality with custom pre/post operation hooks
🌐 **Network Maestro** - Smart network management with CLI overrides
🔐 **Environment Juggler** - Override any environment variable on the fly
🎨 **Beautiful Output** - Color-coded logs and status indicators
🧪 **Dry-Run Mode** - Test changes before applying them
## Quick Example
```bash
# Start all stacks
./kompose.sh "*" up -d
# View logs from specific stacks
./kompose.sh "blog,news" logs -f
# Export all databases
./kompose.sh "*" db:export
# Override network for staging
./kompose.sh --network staging "*" up -d
```
## Key Features
### Stack Management
Pattern-based selection allows you to target stacks with globs, comma-separated lists, or wildcards. Execute commands across multiple stacks simultaneously with visual feedback and color-coded success/failure indicators.
### Database Operations
Automated backups with timestamped dumps, smart imports that auto-detect latest dumps, and safe database operations with connection termination. Keep your storage clean with cleanup utilities.
### Hooks System
Extend Kompose with custom hooks for each stack. Define `pre_db_export`, `post_db_export`, `pre_db_import`, and `post_db_import` hooks to add stack-specific logic.
### Network Management
All stacks communicate through a unified Docker network. Override the network on-the-fly via CLI without editing configs, with seamless Traefik integration.
## Next Steps
- [Installation Guide](/docs/installation)
- [Quick Start Tutorial](/docs/quick-start)
- [Stack Management](/docs/guide/stack-management)
- [Database Operations](/docs/guide/database)

View File

@@ -0,0 +1,280 @@
---
title: Installation Guide
description: Step-by-step guide to install and set up Kompose on your system
---
# Installation Guide
Get Kompose up and running on your system in just a few minutes.
## Prerequisites
Before installing Kompose, make sure you have the following installed:
### Required
- **Bash** 4.0 or higher
- **Docker** 20.10 or higher
- **Docker Compose** v2.0 or higher
### Optional (for database operations)
- **PostgreSQL client tools** (for database operations)
```bash
# Ubuntu/Debian
sudo apt-get install postgresql-client
# macOS
brew install postgresql
# Arch Linux
sudo pacman -S postgresql
```
## Installation
### Method 1: Clone from Git (Recommended)
```bash
# Clone the repository
git clone https://github.com/yourusername/kompose.git
# Navigate to the directory
cd kompose
# Make the script executable
chmod +x kompose.sh
# Verify installation
./kompose.sh --help
```
### Method 2: Download Release
```bash
# Download the latest release
wget https://github.com/yourusername/kompose/archive/refs/heads/main.zip
# Extract
unzip main.zip
# Navigate to directory
cd kompose-main
# Make executable
chmod +x kompose.sh
```
## Initial Setup
### 1. Create Docker Network
Kompose uses a unified Docker network for all stacks:
```bash
docker network create kompose
```
### 2. Configure Environment
Create and configure the root `.env` file:
```bash
# Copy example environment file
cp .env.example .env
# Edit with your preferred editor
nano .env
```
**Example `.env` configuration:**
```env
# Network Configuration
NETWORK_NAME=kompose
# Database Connection
DB_USER=dbuser
DB_PASSWORD=secretpassword
DB_PORT=5432
DB_HOST=postgres
# Admin Settings
ADMIN_EMAIL=admin@example.com
# Email/SMTP Settings
EMAIL_TRANSPORT=smtp
EMAIL_FROM=noreply@example.com
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=465
EMAIL_SMTP_USER=smtp@example.com
EMAIL_SMTP_PASSWORD=smtppassword
```
### 3. Configure Individual Stacks
Each stack needs its own `.env` file. Navigate to any stack directory:
```bash
# Example: Configure the proxy stack
cd proxy
cp .env.example .env
nano .env
```
## Verification
### Check Installation
```bash
# List all available stacks
./kompose.sh --list
# Should output something like:
# Stack: auth (compose.yaml) [.env] [PostgreSQL]
# Stack: blog (compose.yaml) [.env]
# Stack: data (compose.yaml) [.env] [PostgreSQL]
# ...
```
### Test Basic Commands
```bash
# Start the proxy stack
./kompose.sh proxy up -d
# Check if it's running
./kompose.sh proxy ps
# View logs
./kompose.sh proxy logs
```
## Post-Installation
### Add to PATH (Optional)
For easier access, add Kompose to your PATH:
```bash
# Add to ~/.bashrc or ~/.zshrc
echo 'export PATH="$PATH:/path/to/kompose"' >> ~/.bashrc
source ~/.bashrc
# Now you can run from anywhere
kompose.sh --list
```
### Create Aliases (Optional)
Add helpful aliases to your shell configuration:
```bash
# Add to ~/.bashrc or ~/.zshrc
alias kp='./kompose.sh'
alias kup='./kompose.sh "*" up -d'
alias kdown='./kompose.sh "*" down'
alias klogs='./kompose.sh "*" logs -f'
alias kps='./kompose.sh "*" ps'
```
### Set Up Automated Backups
Create a cron job for automatic database backups:
```bash
# Edit crontab
crontab -e
# Add daily backup at 2 AM
0 2 * * * cd /path/to/kompose && ./kompose.sh "*" db:export 2>&1 | tee -a backup.log
# Add weekly cleanup (Sundays at 3 AM)
0 3 * * 0 cd /path/to/kompose && ./kompose.sh "*" db:cleanup
```
## Troubleshooting
### Permission Denied
If you get a "Permission denied" error:
```bash
chmod +x kompose.sh
```
### Docker Network Already Exists
If the network creation fails:
```bash
# Check if it exists
docker network ls | grep kompose
# If it exists, you're good to go
# If not, try removing and recreating
docker network rm kompose
docker network create kompose
```
### Docker Not Running
Ensure Docker daemon is running:
```bash
# Check Docker status
sudo systemctl status docker
# Start Docker if not running
sudo systemctl start docker
# Enable Docker to start on boot
sudo systemctl enable docker
```
## Next Steps
Now that Kompose is installed, you can:
1. [Start with the Quick Start Guide](/docs/quick-start)
2. [Learn about Stack Management](/docs/guide/stack-management)
3. [Explore Database Operations](/docs/guide/database)
4. [Set up Custom Hooks](/docs/guide/hooks)
## Updating Kompose
To update to the latest version:
```bash
# Navigate to Kompose directory
cd /path/to/kompose
# Pull latest changes
git pull origin main
# Restart affected stacks if needed
./kompose.sh "*" restart
```
## Uninstallation
To completely remove Kompose:
```bash
# Stop all stacks
./kompose.sh "*" down
# Remove Docker network
docker network rm kompose
# Remove Kompose directory
rm -rf /path/to/kompose
# (Optional) Remove from PATH
# Edit ~/.bashrc or ~/.zshrc and remove the PATH export
```
---
**Need Help?** Check out the [Troubleshooting Guide](/docs/troubleshooting) or [open an issue](https://github.com/yourusername/kompose/issues) on GitHub.

View File

@@ -0,0 +1,222 @@
<template>
<div class="flex flex-col min-h-screen">
<!-- Header -->
<header class="sticky top-0 z-50 w-full border-b border-dark-800 glass-dark">
<div class="container mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex h-16 items-center justify-between">
<!-- Logo -->
<NuxtLink to="/" class="flex items-center space-x-3 group">
<div class="text-3xl font-bold gradient-text group-hover:scale-110 transition-transform">
KOMPOSE
</div>
</NuxtLink>
<!-- Navigation -->
<nav class="hidden md:flex items-center space-x-6">
<NuxtLink to="/docs" class="link-fancy text-sm font-medium">
Documentation
</NuxtLink>
<NuxtLink to="/api" class="link-fancy text-sm font-medium">
API Reference
</NuxtLink>
<NuxtLink to="/examples" class="link-fancy text-sm font-medium">
Examples
</NuxtLink>
<a href="https://github.com/yourusername/kompose" target="_blank"
class="text-gray-400 hover:text-white transition-colors">
<Icon name="lucide:github" class="w-5 h-5" />
</a>
</nav>
<!-- Mobile menu button -->
<button @click="mobileMenuOpen = !mobileMenuOpen" class="md:hidden text-gray-400 hover:text-white">
<Icon :name="mobileMenuOpen ? 'lucide:x' : 'lucide:menu'" class="w-6 h-6" />
</button>
</div>
</div>
<!-- Mobile menu -->
<Transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="opacity-0 scale-95"
enter-to-class="opacity-100 scale-100"
leave-active-class="transition duration-100 ease-in"
leave-from-class="opacity-100 scale-100"
leave-to-class="opacity-0 scale-95"
>
<div v-show="mobileMenuOpen" class="md:hidden border-t border-dark-800 bg-dark-900 p-4">
<nav class="flex flex-col space-y-3">
<NuxtLink @click="mobileMenuOpen = false" to="/docs" class="text-gray-300 hover:text-white">
Documentation
</NuxtLink>
<NuxtLink @click="mobileMenuOpen = false" to="/api" class="text-gray-300 hover:text-white">
API Reference
</NuxtLink>
<NuxtLink @click="mobileMenuOpen = false" to="/examples" class="text-gray-300 hover:text-white">
Examples
</NuxtLink>
</nav>
</div>
</Transition>
</header>
<div class="flex-1 flex">
<!-- Sidebar -->
<aside class="hidden lg:block w-64 border-r border-dark-800 overflow-y-auto sticky top-16 h-[calc(100vh-4rem)]">
<div class="p-6 space-y-6">
<!-- Search -->
<div class="relative">
<Icon name="lucide:search" class="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-500" />
<input
type="search"
placeholder="Search docs..."
class="w-full pl-10 pr-4 py-2 bg-dark-900 border border-dark-700 rounded-lg text-sm focus:outline-none focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20"
/>
</div>
<!-- Navigation sections -->
<nav class="space-y-6">
<div v-for="section in navigation" :key="section.title">
<h3 class="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3">
{{ section.title }}
</h3>
<ul class="space-y-1">
<li v-for="item in section.items" :key="item.to">
<NuxtLink :to="item.to" class="sidebar-link">
{{ item.label }}
</NuxtLink>
</li>
</ul>
</div>
</nav>
</div>
</aside>
<!-- Main content -->
<main class="flex-1 overflow-x-hidden">
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-8 max-w-5xl">
<slot />
</div>
</main>
<!-- Table of contents -->
<aside class="hidden xl:block w-64 border-l border-dark-800 overflow-y-auto sticky top-16 h-[calc(100vh-4rem)]">
<div class="p-6">
<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
On This Page
</h3>
<nav class="space-y-2">
<a
v-for="link in toc"
:key="link.id"
:href="`#${link.id}`"
class="toc-link"
:class="{ active: activeId === link.id }"
:style="{ paddingLeft: `${(link.depth - 2) * 12 + 16}px` }"
>
{{ link.text }}
</a>
</nav>
</div>
</aside>
</div>
<!-- Footer -->
<footer class="border-t border-dark-800 bg-dark-950">
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div class="col-span-1 md:col-span-2">
<div class="text-2xl font-bold gradient-text mb-4">KOMPOSE</div>
<p class="text-gray-400 text-sm mb-4">
Your Docker Compose Symphony Conductor
</p>
<div class="flex space-x-4">
<a href="#" class="text-gray-400 hover:text-primary-400 transition-colors">
<Icon name="lucide:github" class="w-5 h-5" />
</a>
<a href="#" class="text-gray-400 hover:text-primary-400 transition-colors">
<Icon name="lucide:twitter" class="w-5 h-5" />
</a>
</div>
</div>
<div>
<h4 class="text-sm font-semibold text-white mb-4">Documentation</h4>
<ul class="space-y-2 text-sm">
<li><NuxtLink to="/docs" class="text-gray-400 hover:text-white">Getting Started</NuxtLink></li>
<li><NuxtLink to="/docs/guide" class="text-gray-400 hover:text-white">Guide</NuxtLink></li>
<li><NuxtLink to="/api" class="text-gray-400 hover:text-white">API Reference</NuxtLink></li>
</ul>
</div>
<div>
<h4 class="text-sm font-semibold text-white mb-4">Community</h4>
<ul class="space-y-2 text-sm">
<li><a href="#" class="text-gray-400 hover:text-white">GitHub</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Discord</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Twitter</a></li>
</ul>
</div>
</div>
<div class="border-t border-dark-800 mt-8 pt-8 text-center text-sm text-gray-400">
<p>&copy; 2025 Kompose. Made with and </p>
</div>
</div>
</footer>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const mobileMenuOpen = ref(false)
const activeId = ref('')
const toc = ref([])
const navigation = [
{
title: 'Getting Started',
items: [
{ label: 'Introduction', to: '/docs' },
{ label: 'Installation', to: '/docs/installation' },
{ label: 'Quick Start', to: '/docs/quick-start' },
]
},
{
title: 'Guide',
items: [
{ label: 'Stack Management', to: '/docs/guide/stack-management' },
{ label: 'Database Operations', to: '/docs/guide/database' },
{ label: 'Hooks System', to: '/docs/guide/hooks' },
{ label: 'Network Architecture', to: '/docs/guide/network' },
]
},
{
title: 'Reference',
items: [
{ label: 'Configuration', to: '/docs/reference/configuration' },
{ label: 'CLI Commands', to: '/docs/reference/cli' },
{ label: 'Environment Variables', to: '/docs/reference/env' },
]
}
]
// Table of contents intersection observer
onMounted(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
activeId.value = entry.target.id
}
})
},
{ rootMargin: '-80px 0px -80% 0px' }
)
document.querySelectorAll('h2, h3').forEach((heading) => {
observer.observe(heading)
})
})
</script>

View File

@@ -0,0 +1,82 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
gzip_disable "msie6";
# Brotli compression (if available)
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Handle SPA routing
location / {
try_files $uri $uri/ /index.html;
}
# Handle 404 errors
error_page 404 /404.html;
location = /404.html {
internal;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}

View File

@@ -0,0 +1,115 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-04-03',
devtools: { enabled: true },
modules: [
'@nuxt/content',
'@nuxtjs/tailwindcss',
'@nuxtjs/color-mode',
'@nuxt/icon',
'@vueuse/nuxt'
],
// Content module configuration
content: {
documentDriven: true,
highlight: {
theme: {
default: 'github-dark',
dark: 'github-dark'
},
preload: [
'bash',
'shell',
'yaml',
'json',
'markdown',
'javascript',
'typescript',
'vue',
'docker',
'sql'
]
},
markdown: {
toc: {
depth: 3,
searchDepth: 3
},
anchorLinks: true
},
// Search configuration
experimental: {
search: {
indexed: true
}
}
},
// Color mode configuration
colorMode: {
classSuffix: '',
preference: 'dark',
fallback: 'dark'
},
// Tailwind configuration
tailwindcss: {
exposeConfig: true,
viewer: true,
config: {
darkMode: 'class',
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./app.vue'
]
}
},
// App configuration
app: {
head: {
charset: 'utf-8',
viewport: 'width=device-width, initial-scale=1',
title: 'Kompose Documentation',
meta: [
{ name: 'description', content: 'Complete documentation for Kompose - Your Docker Compose Symphony Conductor' },
{ name: 'og:title', content: 'Kompose Documentation' },
{ name: 'og:description', content: 'Complete documentation for Kompose - Your Docker Compose Symphony Conductor' },
{ name: 'og:type', content: 'website' },
{ name: 'twitter:card', content: 'summary_large_image' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}
},
// Nitro configuration for static generation
nitro: {
prerender: {
crawlLinks: true,
routes: ['/']
}
},
// Build configuration
build: {
transpile: []
},
// PWA configuration
pwa: {
manifest: {
name: 'Kompose Docs',
short_name: 'Kompose',
description: 'Kompose Documentation',
theme_color: '#f97316',
background_color: '#0a0a0a'
}
}
})

View File

@@ -0,0 +1,31 @@
{
"name": "kompose-docs",
"version": "1.0.0",
"description": "Kompose Documentation Site",
"private": true,
"type": "module",
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@nuxt/content": "^2.13.2",
"@nuxtjs/color-mode": "^3.4.2",
"@nuxtjs/tailwindcss": "^6.12.1",
"nuxt": "^3.13.2",
"vue": "^3.5.4",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@iconify-json/heroicons": "^1.2.0",
"@iconify-json/lucide": "^1.2.4",
"@nuxt/icon": "^1.5.2",
"@tailwindcss/typography": "^0.5.15",
"@vueuse/core": "^11.1.0",
"@vueuse/nuxt": "^11.1.0"
},
"packageManager": "pnpm@9.0.0"
}

View File

@@ -0,0 +1,143 @@
<template>
<div class="docs-page">
<article class="prose prose-lg max-w-none">
<ContentDoc v-slot="{ doc }">
<div>
<!-- Page header -->
<div class="mb-8 pb-8 border-b border-dark-800">
<h1 class="text-5xl font-bold gradient-text mb-4">
{{ doc.title }}
</h1>
<p v-if="doc.description" class="text-xl text-gray-400">
{{ doc.description }}
</p>
</div>
<!-- Content -->
<ContentRenderer :value="doc" class="markdown-content" />
<!-- Navigation -->
<div class="mt-16 pt-8 border-t border-dark-800 flex justify-between items-center">
<NuxtLink
v-if="doc.prev"
:to="doc.prev.path"
class="flex items-center gap-2 text-primary-400 hover:text-primary-300 transition-colors"
>
<Icon name="lucide:arrow-left" class="w-5 h-5" />
<span>{{ doc.prev.title }}</span>
</NuxtLink>
<div v-else></div>
<NuxtLink
v-if="doc.next"
:to="doc.next.path"
class="flex items-center gap-2 text-primary-400 hover:text-primary-300 transition-colors"
>
<span>{{ doc.next.title }}</span>
<Icon name="lucide:arrow-right" class="w-5 h-5" />
</NuxtLink>
<div v-else></div>
</div>
</div>
</ContentDoc>
</article>
</div>
</template>
<script setup>
definePageMeta({
layout: 'default'
})
</script>
<style scoped>
.markdown-content :deep(h2) {
@apply text-3xl font-bold text-white mt-12 mb-6 flex items-center gap-3;
}
.markdown-content :deep(h2::before) {
content: '';
@apply w-1 h-8 bg-gradient-primary rounded;
}
.markdown-content :deep(h3) {
@apply text-2xl font-semibold text-white mt-8 mb-4;
}
.markdown-content :deep(p) {
@apply text-gray-300 leading-relaxed mb-6;
}
.markdown-content :deep(ul),
.markdown-content :deep(ol) {
@apply space-y-2 mb-6;
}
.markdown-content :deep(li) {
@apply text-gray-300;
}
.markdown-content :deep(code) {
@apply bg-dark-800 text-primary-300 px-2 py-1 rounded text-sm font-mono;
}
.markdown-content :deep(pre) {
@apply bg-dark-900 border border-dark-700 rounded-lg p-6 overflow-x-auto mb-6 relative group;
}
.markdown-content :deep(pre code) {
@apply bg-transparent text-gray-300 p-0;
}
.markdown-content :deep(blockquote) {
@apply border-l-4 border-primary-500 pl-6 py-2 my-6 bg-dark-900/50 rounded-r-lg;
}
.markdown-content :deep(blockquote p) {
@apply text-gray-400 italic;
}
.markdown-content :deep(a) {
@apply text-primary-400 hover:text-primary-300 underline decoration-primary-500/30 hover:decoration-primary-400 transition-colors;
}
.markdown-content :deep(table) {
@apply w-full border-collapse mb-6;
}
.markdown-content :deep(th) {
@apply bg-dark-800 text-primary-400 font-semibold py-3 px-4 text-left border-b-2 border-primary-500/30;
}
.markdown-content :deep(td) {
@apply py-3 px-4 border-b border-dark-700;
}
.markdown-content :deep(tr:hover) {
@apply bg-white/5;
}
.markdown-content :deep(img) {
@apply rounded-lg shadow-glow-cyber my-6;
}
.markdown-content :deep(.alert) {
@apply p-4 rounded-lg mb-6 border-l-4;
}
.markdown-content :deep(.alert-info) {
@apply bg-blue-500/10 border-blue-500;
}
.markdown-content :deep(.alert-warning) {
@apply bg-yellow-500/10 border-yellow-500;
}
.markdown-content :deep(.alert-danger) {
@apply bg-red-500/10 border-red-500;
}
.markdown-content :deep(.alert-success) {
@apply bg-green-500/10 border-green-500;
}
</style>

View File

@@ -0,0 +1,234 @@
<template>
<div class="relative overflow-hidden">
<!-- Hero section -->
<section class="relative py-20 lg:py-32">
<!-- Background decorations -->
<div class="absolute top-0 left-1/4 hero-blob bg-primary-500/20 animate-float" style="animation-delay: 0s"></div>
<div class="absolute bottom-0 right-1/4 hero-blob bg-accent-500/20 animate-float" style="animation-delay: 2s"></div>
<div class="container mx-auto px-4 relative z-10">
<div class="max-w-4xl mx-auto text-center">
<!-- Main heading with gradient -->
<h1 class="text-6xl md:text-8xl font-black mb-6 gradient-text-hero">
KOMPOSE
</h1>
<p class="text-2xl md:text-3xl text-gray-300 mb-8 font-light">
Your Docker Compose Symphony Conductor
</p>
<p class="text-lg text-gray-400 mb-12 max-w-2xl mx-auto">
Manage multiple Docker Compose stacks with style and grace.
One command to rule them all, with beautiful output and powerful features.
</p>
<!-- CTA Buttons -->
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
<NuxtLink to="/docs" class="btn-primary text-lg px-8 py-4">
<span class="flex items-center gap-2">
<Icon name="lucide:book-open" class="w-5 h-5" />
Get Started
</span>
</NuxtLink>
<NuxtLink to="/docs/quick-start" class="btn-ghost text-lg px-8 py-4">
<span class="flex items-center gap-2">
<Icon name="lucide:zap" class="w-5 h-5" />
Quick Start
</span>
</NuxtLink>
</div>
<!-- Installation command -->
<div class="mt-12 glass-dark rounded-xl p-6 inline-block">
<div class="flex items-center justify-between gap-4">
<code class="text-primary-400 text-sm font-mono">
git clone https://github.com/yourusername/kompose.git
</code>
<button @click="copyCommand" class="text-gray-400 hover:text-white transition-colors">
<Icon :name="copied ? 'lucide:check' : 'lucide:copy'" class="w-5 h-5" />
</button>
</div>
</div>
</div>
</div>
</section>
<!-- Features section -->
<section class="py-20 relative">
<div class="container mx-auto px-4">
<div class="text-center mb-16">
<h2 class="text-4xl md:text-5xl font-bold mb-4 gradient-text">
Powerful Features
</h2>
<p class="text-xl text-gray-400">
Everything you need to manage your Docker infrastructure
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div v-for="feature in features" :key="feature.title"
class="card-glow group hover:-translate-y-2">
<div class="mb-4">
<div class="w-12 h-12 rounded-lg bg-gradient-primary flex items-center justify-center">
<Icon :name="feature.icon" class="w-6 h-6 text-white" />
</div>
</div>
<h3 class="text-xl font-semibold text-white mb-3">
{{ feature.title }}
</h3>
<p class="text-gray-400">
{{ feature.description }}
</p>
</div>
</div>
</div>
</section>
<!-- Code example section -->
<section class="py-20 bg-dark-900/50">
<div class="container mx-auto px-4">
<div class="max-w-4xl mx-auto">
<div class="text-center mb-12">
<h2 class="text-4xl md:text-5xl font-bold mb-4 gradient-text">
Simple Yet Powerful
</h2>
<p class="text-xl text-gray-400">
Manage all your stacks with intuitive commands
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div v-for="example in examples" :key="example.title" class="card-glass">
<h3 class="text-lg font-semibold text-white mb-4 flex items-center gap-2">
<Icon name="lucide:terminal" class="w-5 h-5 text-primary-400" />
{{ example.title }}
</h3>
<pre class="bg-dark-950 p-4 rounded-lg overflow-x-auto">
<code class="text-sm text-gray-300">{{ example.code }}</code></pre>
</div>
</div>
<div class="text-center mt-12">
<NuxtLink to="/docs" class="btn-accent px-8 py-4">
<span class="flex items-center gap-2">
Explore Full Documentation
<Icon name="lucide:arrow-right" class="w-5 h-5" />
</span>
</NuxtLink>
</div>
</div>
</div>
</section>
<!-- Stats section -->
<section class="py-20">
<div class="container mx-auto px-4">
<div class="max-w-5xl mx-auto grid grid-cols-1 md:grid-cols-3 gap-8">
<div v-for="stat in stats" :key="stat.label"
class="text-center card-glass">
<div class="text-5xl font-bold gradient-text mb-2">
{{ stat.value }}
</div>
<div class="text-gray-400">
{{ stat.label }}
</div>
</div>
</div>
</div>
</section>
<!-- CTA section -->
<section class="py-20 relative">
<div class="absolute inset-0 bg-gradient-hero opacity-10"></div>
<div class="container mx-auto px-4 relative z-10">
<div class="max-w-3xl mx-auto text-center">
<h2 class="text-4xl md:text-5xl font-bold mb-6 text-white">
Ready to Conduct Your Docker Symphony?
</h2>
<p class="text-xl text-gray-300 mb-8">
Get started with Kompose today and simplify your Docker workflow
</p>
<NuxtLink to="/docs/installation" class="btn-primary text-lg px-8 py-4">
<span class="flex items-center gap-2">
<Icon name="lucide:download" class="w-5 h-5" />
Install Now
</span>
</NuxtLink>
</div>
</div>
</section>
</div>
</template>
<script setup>
import { ref } from 'vue'
const copied = ref(false)
const features = [
{
title: 'Stack Management',
icon: 'lucide:layers',
description: 'Manage multiple Docker Compose stacks with pattern-based selection and bulk operations.'
},
{
title: 'Database Operations',
icon: 'lucide:database',
description: 'Automated backups, smart imports, and database cleanup with PostgreSQL support.'
},
{
title: 'Hooks System',
icon: 'lucide:git-branch',
description: 'Extend functionality with custom pre/post operation hooks for each stack.'
},
{
title: 'Network Maestro',
icon: 'lucide:network',
description: 'Smart network management with CLI overrides and seamless Traefik integration.'
},
{
title: 'Environment Control',
icon: 'lucide:settings',
description: 'Override environment variables on-the-fly without editing configuration files.'
},
{
title: 'Beautiful Output',
icon: 'lucide:sparkles',
description: 'Color-coded logs, status indicators, and intuitive command-line interface.'
}
]
const examples = [
{
title: 'Start Everything',
code: './kompose.sh "*" up -d'
},
{
title: 'Export Databases',
code: './kompose.sh "*" db:export'
},
{
title: 'View Logs',
code: './kompose.sh "blog,news" logs -f'
},
{
title: 'Override Network',
code: './kompose.sh --network staging "*" up'
}
]
const stats = [
{ value: '10+', label: 'Production Stacks' },
{ value: '100%', label: 'Bash Powered' },
{ value: '1', label: 'Command to Rule Them All' }
]
const copyCommand = () => {
navigator.clipboard.writeText('git clone https://github.com/yourusername/kompose.git')
copied.value = true
setTimeout(() => {
copied.value = false
}, 2000)
}
</script>

View File

@@ -0,0 +1,168 @@
/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class',
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./app.vue',
'./content/**/*.md'
],
theme: {
extend: {
colors: {
// Dark base colors
dark: {
50: '#f5f5f5',
100: '#e7e7e7',
200: '#d1d1d1',
300: '#b0b0b0',
400: '#888888',
500: '#6d6d6d',
600: '#5d5d5d',
700: '#4f4f4f',
800: '#454545',
900: '#3d3d3d',
950: '#0a0a0a',
},
// Orange primary colors (funky modern)
primary: {
50: '#fff7ed',
100: '#ffedd5',
200: '#fed7aa',
300: '#fdba74',
400: '#fb923c',
500: '#f97316', // Main orange
600: '#ea580c',
700: '#c2410c',
800: '#9a3412',
900: '#7c2d12',
950: '#431407',
},
// Purple accent colors
accent: {
50: '#faf5ff',
100: '#f3e8ff',
200: '#e9d5ff',
300: '#d8b4fe',
400: '#c084fc',
500: '#a855f7', // Main purple
600: '#9333ea',
700: '#7e22ce',
800: '#6b21a8',
900: '#581c87',
950: '#3b0764',
},
// Complementary colors
cyber: {
pink: '#ff0080',
cyan: '#00f5ff',
lime: '#39ff14'
}
},
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
'gradient-primary': 'linear-gradient(135deg, #f97316 0%, #fb923c 100%)',
'gradient-accent': 'linear-gradient(135deg, #a855f7 0%, #c084fc 100%)',
'gradient-hero': 'linear-gradient(135deg, #f97316 0%, #a855f7 50%, #7e22ce 100%)',
'gradient-cyber': 'linear-gradient(135deg, #f97316 0%, #ff0080 50%, #a855f7 100%)',
'gradient-dark': 'linear-gradient(180deg, #0a0a0a 0%, #1a1a1a 100%)',
'gradient-shine': 'linear-gradient(90deg, transparent, rgba(249, 115, 22, 0.3), transparent)',
},
animation: {
'gradient': 'gradient 8s linear infinite',
'gradient-xy': 'gradient-xy 15s ease infinite',
'shimmer': 'shimmer 2s linear infinite',
'glow': 'glow 2s ease-in-out infinite alternate',
'float': 'float 6s ease-in-out infinite',
'pulse-slow': 'pulse 4s cubic-bezier(0.4, 0, 0.6, 1) infinite',
},
keyframes: {
gradient: {
'0%, 100%': {
'background-size': '200% 200%',
'background-position': 'left center'
},
'50%': {
'background-size': '200% 200%',
'background-position': 'right center'
},
},
'gradient-xy': {
'0%, 100%': {
'background-size': '400% 400%',
'background-position': 'left center'
},
'50%': {
'background-size': '200% 200%',
'background-position': 'right center'
},
},
shimmer: {
'0%': { transform: 'translateX(-100%)' },
'100%': { transform: 'translateX(100%)' }
},
glow: {
'from': {
'text-shadow': '0 0 10px #f97316, 0 0 20px #f97316, 0 0 30px #f97316',
},
'to': {
'text-shadow': '0 0 20px #a855f7, 0 0 30px #a855f7, 0 0 40px #a855f7',
}
},
float: {
'0%, 100%': { transform: 'translateY(0px)' },
'50%': { transform: 'translateY(-20px)' }
}
},
boxShadow: {
'glow-orange': '0 0 20px rgba(249, 115, 22, 0.5)',
'glow-purple': '0 0 20px rgba(168, 85, 247, 0.5)',
'glow-cyber': '0 0 30px rgba(249, 115, 22, 0.3), 0 0 60px rgba(168, 85, 247, 0.3)',
'inner-glow': 'inset 0 0 20px rgba(249, 115, 22, 0.2)',
},
typography: (theme) => ({
DEFAULT: {
css: {
'--tw-prose-body': theme('colors.gray[300]'),
'--tw-prose-headings': theme('colors.white'),
'--tw-prose-links': theme('colors.primary[400]'),
'--tw-prose-bold': theme('colors.white'),
'--tw-prose-code': theme('colors.primary[300]'),
'--tw-prose-pre-bg': theme('colors.dark[900]'),
maxWidth: 'none',
color: theme('colors.gray[300]'),
a: {
color: theme('colors.primary[400]'),
'&:hover': {
color: theme('colors.primary[500]'),
},
},
'code::before': {
content: '""'
},
'code::after': {
content: '""'
},
code: {
color: theme('colors.primary[300]'),
backgroundColor: theme('colors.dark[800]'),
padding: '0.25rem 0.5rem',
borderRadius: '0.25rem',
fontWeight: '500',
},
pre: {
backgroundColor: theme('colors.dark[900]'),
border: `1px solid ${theme('colors.dark[700]')}`,
}
}
}
})
},
},
plugins: [
require('@tailwindcss/typography'),
],
}

View File

@@ -0,0 +1,3 @@
{
"extends": "./.nuxt/tsconfig.json"
}