docs: Update README and CHANGELOG with web assets optimization
- Document web assets restructuring with minification pipeline * 32% compression (26KB → 18KB) * Bilingual support (EN/ES) preserved * Automated minify.sh script for version sync * Complete README.md guide with examples - Add web assets structure to project directory layout in README - New assets/web/ section with source and production versions - Reference to minification script and documentation - Include Just recipes documentation for local development - Show `just help` commands for discovering available recipes - Document 50+ recipes for build, test, and CI operations - Update CHANGELOG with infrastructure improvements - Web assets optimization (32% compression) - Just recipes CI/CD system (50+ commands) - Code quality improvements and bug fixes - Markdown linting compliance achieved - All tests passing (55/55 in vapora-backend) - Add build and test results to unreleased changes section - Clean compilation with 0 warnings in vapora-backend - 55 tests passing - Clippy compliance achieved
This commit is contained in:
parent
d14150da75
commit
8f6a884f6e
48
CHANGELOG.md
48
CHANGELOG.md
@ -9,9 +9,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- Intelligent learning system for multi-agent coordination
|
||||
- Cost optimization with budget enforcement
|
||||
- Gradual production deployment guide
|
||||
- **Web Assets Optimization**: Restructured landing page with minification pipeline
|
||||
- Separated source (`assets/web/src/index.html`) from minified production version
|
||||
- Automated minification script (`assets/web/minify.sh`) for version synchronization
|
||||
- 32% compression achieved (26KB → 18KB)
|
||||
- Bilingual content (English/Spanish) preserved with localStorage persistence
|
||||
- Complete documentation in `assets/web/README.md`
|
||||
|
||||
- **Infrastructure & Build System**
|
||||
- Just recipes for CI/CD automation (50+ recipes organized by category)
|
||||
- Parametrized help system for command discovery
|
||||
- Integration with development workflows
|
||||
|
||||
### Changed
|
||||
|
||||
- **Code Quality Improvements**
|
||||
- Removed unused imports from API and workflow modules (5+ files)
|
||||
- Fixed 6 unnecessary `mut` keyword warnings in provider analytics
|
||||
- Improved code patterns: converted verbose match to `matches!` macro (workflow/state.rs)
|
||||
- Applied automatic clippy fixes for idiomatic Rust
|
||||
|
||||
- **Documentation & Linting**
|
||||
- Fixed markdown linting compliance in `assets/web/README.md`
|
||||
- Proper code fence language specifications (MD040)
|
||||
- Blank lines around code blocks (MD031)
|
||||
- Table formatting with compact style (MD060)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Compilation & Testing**
|
||||
- Eliminated all unused import warnings in vapora-backend
|
||||
- Suppressed architectural dead code with appropriate attributes
|
||||
- All 55 tests passing in vapora-backend
|
||||
- 0 compilation errors, clean build output
|
||||
|
||||
### Technical Details
|
||||
|
||||
- **Architecture**: Refactored unused imports from workflow and API modules
|
||||
- Tests moved to test-only scope for AgentConfig/RegistryConfig types
|
||||
- Intentional suppression for components not yet integrated
|
||||
- Future-proof markers for architectural patterns
|
||||
|
||||
- **Build Status**: Clean compilation pipeline
|
||||
- `cargo build -p vapora-backend` ✅
|
||||
- `cargo clippy -p vapora-backend` ✅ (5 nesting suggestions only)
|
||||
- `cargo test -p vapora-backend` ✅ (55/55 passing)
|
||||
|
||||
## [1.2.0] - 2026-01-11
|
||||
|
||||
|
||||
13
README.md
13
README.md
@ -185,6 +185,12 @@
|
||||
# Install dependencies
|
||||
cargo build
|
||||
|
||||
# Available Just recipes (50+ commands)
|
||||
just help # Show all available recipes
|
||||
just help build # Show build recipes
|
||||
just help test # Show test recipes
|
||||
just help ci # Show CI recipes
|
||||
|
||||
# Setup SurrealDB (Docker)
|
||||
docker run -d --name surrealdb \
|
||||
-p 8000:8000 \
|
||||
@ -356,6 +362,13 @@ provisioning workflow run workflows/deploy-full-stack.yaml
|
||||
│ ├── vapora-analytics/ # Event pipeline + usage stats
|
||||
│ ├── vapora-worktree/ # Git worktree management
|
||||
│ └── vapora-doc-lifecycle/ # Documentation management
|
||||
├── assets/
|
||||
│ ├── web/ # Landing page (optimized + minified)
|
||||
│ │ ├── src/index.html # Source (readable, 26KB)
|
||||
│ │ ├── index.html # Production (minified, 18KB)
|
||||
│ │ ├── minify.sh # Auto-minification script
|
||||
│ │ └── README.md # Web assets guide
|
||||
│ └── vapora.svg # Logo
|
||||
├── kubernetes/ # K8s manifests (base, overlays, platform)
|
||||
├── migrations/ # SurrealDB migrations
|
||||
├── config/ # Configuration files (TOML)
|
||||
|
||||
218
assets/web/README.md
Normal file
218
assets/web/README.md
Normal file
@ -0,0 +1,218 @@
|
||||
# Vapora Web Assets
|
||||
|
||||
Web-based landing page and static content for Vapora.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```text
|
||||
assets/web/
|
||||
├── src/
|
||||
│ └── index.html # Source HTML (readable, 26KB)
|
||||
├── index.html # Minified/Production HTML (18KB)
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
### `src/index.html` - Source Version
|
||||
|
||||
- **Purpose**: Development and maintenance
|
||||
- **Size**: 26KB (uncompressed)
|
||||
- **Content**:
|
||||
- Full formatting and indentation
|
||||
- Inline CSS and JavaScript
|
||||
- Bilingual (English/Spanish) content
|
||||
- Language-aware dynamic switching
|
||||
- Interactive agent showcase
|
||||
- Technology stack display
|
||||
|
||||
**Use for:**
|
||||
- Editing content
|
||||
- Understanding structure
|
||||
- Version control
|
||||
- Making translations updates
|
||||
|
||||
### `index.html` - Production Version
|
||||
|
||||
- **Purpose**: Served to browsers (fast loading)
|
||||
- **Size**: 18KB (32% compression)
|
||||
- **Optimizations**:
|
||||
- Removed all comments
|
||||
- Compressed CSS (removed spaces, combined rules)
|
||||
- Minified JavaScript (single line)
|
||||
- Removed whitespace between tags
|
||||
- Preserved all functionality
|
||||
|
||||
**Use for:**
|
||||
- Production web server
|
||||
- CDN distribution
|
||||
- Browser caching
|
||||
- Fast load times
|
||||
|
||||
## How to Use
|
||||
|
||||
### Development
|
||||
|
||||
Edit `src/index.html`:
|
||||
|
||||
```bash
|
||||
# Edit source file
|
||||
nano assets/web/src/index.html
|
||||
|
||||
# Regenerate minified version (script below)
|
||||
```
|
||||
|
||||
### Update Minified Version
|
||||
|
||||
When you update `src/index.html`, regenerate `index.html`:
|
||||
|
||||
```bash
|
||||
# Using the minification script (Perl)
|
||||
perl -e '
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
open(my $fh, "<", "assets/web/src/index.html") or die $!;
|
||||
my $content = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
|
||||
# Remove comments
|
||||
$content =~ s/<!--.*?-->//gs;
|
||||
|
||||
# Compress whitespace in style tags
|
||||
$content =~ s/(<style[^>]*>)(.*?)(<\/style>)/
|
||||
my $before = $1;
|
||||
my $style = $2;
|
||||
my $after = $3;
|
||||
$style =~ s{\/\*.*?\*\/}{}gs;
|
||||
$style =~ s{\s+}{ }gs;
|
||||
$style =~ s{\s*([{}:;,>+~])\s*}{$1}gs;
|
||||
$before . $style . $after;
|
||||
/gies;
|
||||
|
||||
# Compress whitespace in script tags
|
||||
$content =~ s/(<script[^>]*>)(.*?)(<\/script>)/
|
||||
my $before = $1;
|
||||
my $script = $2;
|
||||
my $after = $3;
|
||||
$script =~ s{\/\/.*$}{}gm;
|
||||
$script =~ s{\s+}{ }gs;
|
||||
$script =~ s{\s*([{}();,])\s*}{$1}gs;
|
||||
$before . $script . $after;
|
||||
/gies;
|
||||
|
||||
# Remove whitespace between tags
|
||||
$content =~ s/>\s+</></gs;
|
||||
$content =~ s/\s+/ /gs;
|
||||
$content =~ s/^\s+|\s+$//g;
|
||||
|
||||
open(my $out, ">", "assets/web/index.html") or die $!;
|
||||
print $out $content;
|
||||
close($out);
|
||||
|
||||
print "✅ Minified version created\n";
|
||||
'
|
||||
```
|
||||
|
||||
### Deployment
|
||||
|
||||
Serve `index.html` from your web server:
|
||||
|
||||
```bash
|
||||
|
||||
# Using Rust
|
||||
cargo install static-web-server
|
||||
static-web-server -d assets/web/
|
||||
|
||||
# Using Python
|
||||
python3 -m http.server --directory assets/web
|
||||
|
||||
# Using Node.js
|
||||
npx http-server assets/web
|
||||
|
||||
# Using nginx
|
||||
# Point root to assets/web/
|
||||
# Serve index.html as default
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
✅ **Responsive Design**
|
||||
- Mobile-first approach
|
||||
- Flexbox layouts
|
||||
- Media queries for mobile
|
||||
|
||||
✅ **Performance**
|
||||
- Inline CSS (no separate requests)
|
||||
- Inline JavaScript (no blocking external scripts)
|
||||
- Minimal dependencies (no frameworks)
|
||||
- 18KB minified size
|
||||
|
||||
✅ **Bilingual**
|
||||
- English and Spanish
|
||||
- LocalStorage persistence
|
||||
- Data attributes for translations
|
||||
- Dynamic language switching
|
||||
|
||||
✅ **Modern CSS**
|
||||
- CSS Gradients
|
||||
- Animations (fadeInUp)
|
||||
- Hover effects
|
||||
- Grid layouts
|
||||
|
||||
✅ **Styling**
|
||||
- Vapora color scheme
|
||||
- Gradient backgrounds
|
||||
- Monospace font (JetBrains Mono)
|
||||
- Smooth transitions
|
||||
|
||||
## Content Sections
|
||||
|
||||
1. **Hero** - Title, tagline, logo
|
||||
2. **Problems** - 4 problems Vapora solves
|
||||
3. **How It Works** - Feature overview
|
||||
4. **Technology Stack** - Tech badges
|
||||
5. **Available Agents** - Agent showcase (12 agents)
|
||||
6. **CTA** - Call-to-action button
|
||||
7. **Footer** - Credits and links
|
||||
|
||||
## Translations
|
||||
|
||||
All text content is bilingual. Edit data attributes in `src/index.html`:
|
||||
|
||||
```html
|
||||
<!-- English/Spanish example -->
|
||||
<span data-en="Hello" data-es="Hola">Hello</span>
|
||||
```
|
||||
|
||||
The JavaScript automatically updates based on selected language.
|
||||
|
||||
## Maintenance
|
||||
|
||||
- Source edits go in `src/index.html`
|
||||
- Regenerate `index.html` when source changes
|
||||
- Both files are versioned in git
|
||||
- Keep them in sync
|
||||
|
||||
## Git Workflow
|
||||
|
||||
```bash
|
||||
# Edit source
|
||||
git add assets/web/src/index.html
|
||||
git add assets/web/index.html
|
||||
git commit -m "Update landing page content"
|
||||
git push
|
||||
```
|
||||
|
||||
## Compression Statistics
|
||||
|
||||
|File|Size|Type|
|
||||
|---|---|---|
|
||||
|`src/index.html`|26KB|Source (readable)|
|
||||
|`index.html`|18KB|Production (minified)|
|
||||
|**Compression**|**32%**|**Saved 8.8KB**|
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-01-11
|
||||
**Version**: 1.2.0 (matches Vapora release)
|
||||
1
assets/web/index.html
Normal file
1
assets/web/index.html
Normal file
File diff suppressed because one or more lines are too long
87
assets/web/minify.sh
Executable file
87
assets/web/minify.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
# Minify index.html from src/ to production version
|
||||
# Usage: ./minify.sh
|
||||
|
||||
set -e
|
||||
|
||||
SRC_FILE="$(dirname "$0")/src/index.html"
|
||||
OUT_FILE="$(dirname "$0")/index.html"
|
||||
TEMP_FILE="${OUT_FILE}.tmp"
|
||||
|
||||
if [ ! -f "$SRC_FILE" ]; then
|
||||
echo "❌ Source file not found: $SRC_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔨 Minifying HTML..."
|
||||
echo " Input: $SRC_FILE"
|
||||
echo " Output: $OUT_FILE"
|
||||
|
||||
perl -e "
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
open(my \$fh, '<', '$SRC_FILE') or die \$!;
|
||||
my \$content = do { local \$/; <\$fh> };
|
||||
close(\$fh);
|
||||
|
||||
# Remove HTML comments
|
||||
\$content =~ s/<!--.*?-->//gs;
|
||||
|
||||
# Compress CSS (remove spaces and comments)
|
||||
\$content =~ s/(<style[^>]*>)(.*?)(<\/style>)/
|
||||
my \$before = \$1;
|
||||
my \$style = \$2;
|
||||
my \$after = \$3;
|
||||
\$style =~ s{\/\*.*?\*\/}{}gs;
|
||||
\$style =~ s{\s+}{ }gs;
|
||||
\$style =~ s{\s*([{}:;,>+~])\s*}{\$1}gs;
|
||||
\$before . \$style . \$after;
|
||||
/gies;
|
||||
|
||||
# Compress JavaScript (remove comments and extra spaces)
|
||||
\$content =~ s/(<script[^>]*>)(.*?)(<\/script>)/
|
||||
my \$before = \$1;
|
||||
my \$script = \$2;
|
||||
my \$after = \$3;
|
||||
\$script =~ s{\/\/.*\$}{}gm;
|
||||
\$script =~ s{\s+}{ }gs;
|
||||
\$script =~ s{\s*([{}();,])\s*}{\$1}gs;
|
||||
\$before . \$script . \$after;
|
||||
/gies;
|
||||
|
||||
# Remove whitespace between tags
|
||||
\$content =~ s/>\s+</></gs;
|
||||
|
||||
# Compress general whitespace
|
||||
\$content =~ s/\s+/ /gs;
|
||||
|
||||
# Trim
|
||||
\$content =~ s/^\s+|\s+\$//g;
|
||||
|
||||
open(my \$out, '>', '$TEMP_FILE') or die \$!;
|
||||
print \$out \$content;
|
||||
close(\$out);
|
||||
" || {
|
||||
echo "❌ Minification failed"
|
||||
rm -f "$TEMP_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
mv "$TEMP_FILE" "$OUT_FILE"
|
||||
|
||||
# Show statistics
|
||||
original=$(wc -c < "$SRC_FILE")
|
||||
minified=$(wc -c < "$OUT_FILE")
|
||||
saved=$((original - minified))
|
||||
percent=$((saved * 100 / original))
|
||||
|
||||
echo ""
|
||||
echo "✅ Minification complete!"
|
||||
echo ""
|
||||
echo "📊 Compression statistics:"
|
||||
printf " Original: %6d bytes\n" "$original"
|
||||
printf " Minified: %6d bytes\n" "$minified"
|
||||
printf " Saved: %6d bytes (%d%%)\n" "$saved" "$percent"
|
||||
echo ""
|
||||
echo "✅ $OUT_FILE is ready for production"
|
||||
868
assets/web/src/index.html
Normal file
868
assets/web/src/index.html
Normal file
@ -0,0 +1,868 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title
|
||||
data-en="Vapora - Intelligent Development Orchestration"
|
||||
data-es="Vapora - Orquestación Inteligente de Desarrollo"
|
||||
>
|
||||
Vapora
|
||||
</title>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
background: #0a0118;
|
||||
color: #ffffff;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.gradient-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background:
|
||||
radial-gradient(
|
||||
circle at 20% 50%,
|
||||
rgba(168, 85, 247, 0.15) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 80% 80%,
|
||||
rgba(34, 211, 238, 0.15) 0%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at 40% 90%,
|
||||
rgba(236, 72, 153, 0.1) 0%,
|
||||
transparent 50%
|
||||
);
|
||||
}
|
||||
|
||||
.language-toggle {
|
||||
position: fixed;
|
||||
top: 2rem;
|
||||
right: 2rem;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(34, 211, 238, 0.3);
|
||||
border-radius: 20px;
|
||||
padding: 0.3rem 0.3rem;
|
||||
}
|
||||
|
||||
.lang-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #94a3b8;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 18px;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
transition: all 0.3s ease;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
}
|
||||
|
||||
.lang-btn.active {
|
||||
background: linear-gradient(135deg, #22d3ee 0%, #a855f7 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.lang-btn:hover {
|
||||
color: #22d3ee;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
padding: 5rem 0 4rem;
|
||||
animation: fadeInUp 0.8s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
background: rgba(34, 211, 238, 0.2);
|
||||
border: 1px solid #22d3ee;
|
||||
color: #22d3ee;
|
||||
padding: 0.5rem 1.5rem;
|
||||
border-radius: 50px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
max-width: 440px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 0 30px rgba(34, 211, 238, 0.4));
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 0.95rem;
|
||||
color: #22d3ee;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.8rem;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 1.5rem;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#22d3ee 0%,
|
||||
#a855f7 50%,
|
||||
#ec4899 100%
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.15rem;
|
||||
color: #cbd5e1;
|
||||
max-width: 800px;
|
||||
margin: 0 auto 2rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #22d3ee;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin: 4rem 0;
|
||||
animation: fadeInUp 0.8s ease-out;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 2rem;
|
||||
color: #22d3ee;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.section-title span {
|
||||
background: linear-gradient(135deg, #ec4899 0%, #a855f7 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.problems-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.problem-card {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border: 1px solid rgba(168, 85, 247, 0.3);
|
||||
border-radius: 12px;
|
||||
padding: 2rem;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.problem-card:hover {
|
||||
transform: translateY(-5px);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-color: rgba(34, 211, 238, 0.5);
|
||||
}
|
||||
|
||||
.problem-number {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
background: linear-gradient(135deg, #22d3ee 0%, #a855f7 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
line-height: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.problem-card h3 {
|
||||
color: #ec4899;
|
||||
font-size: 1.05rem;
|
||||
margin-bottom: 0.7rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.problem-card p {
|
||||
color: #cbd5e1;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.tech-stack {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tech-badge {
|
||||
background: rgba(34, 211, 238, 0.15);
|
||||
border: 1px solid #22d3ee;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.8rem;
|
||||
color: #22d3ee;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.feature-box {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(34, 211, 238, 0.1) 0%,
|
||||
rgba(168, 85, 247, 0.1) 100%
|
||||
);
|
||||
border-radius: 12px;
|
||||
padding: 2rem;
|
||||
border-left: 4px solid #22d3ee;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-box:hover {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(34, 211, 238, 0.15) 0%,
|
||||
rgba(168, 85, 247, 0.15) 100%
|
||||
);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
color: #22d3ee;
|
||||
margin-bottom: 0.7rem;
|
||||
}
|
||||
|
||||
.feature-text {
|
||||
color: #cbd5e1;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.agents-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.agent-item {
|
||||
background: rgba(236, 72, 153, 0.1);
|
||||
padding: 1.2rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.9rem;
|
||||
border: 1px solid rgba(236, 72, 153, 0.3);
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.agent-item:hover {
|
||||
background: rgba(236, 72, 153, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.agent-name {
|
||||
color: #ec4899;
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
.agent-role {
|
||||
color: #94a3b8;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
text-align: center;
|
||||
margin: 5rem 0 3rem;
|
||||
padding: 4rem 2rem;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(34, 211, 238, 0.1) 0%,
|
||||
rgba(236, 72, 153, 0.1) 100%
|
||||
);
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(168, 85, 247, 0.3);
|
||||
}
|
||||
|
||||
.cta-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 1rem;
|
||||
background: linear-gradient(135deg, #22d3ee 0%, #ec4899 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#22d3ee 0%,
|
||||
#a855f7 50%,
|
||||
#ec4899 100%
|
||||
);
|
||||
color: #fff;
|
||||
padding: 1.1rem 2.8rem;
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: 800;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 10px 30px rgba(34, 211, 238, 0.3);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-3px) scale(1.05);
|
||||
box-shadow: 0 20px 50px rgba(34, 211, 238, 0.5);
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 3rem 0 2rem;
|
||||
color: #64748b;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
margin-top: 4rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
footer p:first-child {
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
footer p:last-child {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
.hero-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.logo-container img {
|
||||
max-width: 352px;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
.cta-title {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
.language-toggle {
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="gradient-bg"></div>
|
||||
|
||||
<div class="language-toggle">
|
||||
<button
|
||||
class="lang-btn active"
|
||||
data-lang="en"
|
||||
onclick="switchLanguage('en')"
|
||||
>
|
||||
EN
|
||||
</button>
|
||||
<button class="lang-btn" data-lang="es" onclick="switchLanguage('es')">
|
||||
ES
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<header>
|
||||
<span class="status-badge" data-en="✅ v1.2.0" data-es="✅ v1.2.0"
|
||||
>✅ v1.2.0</span
|
||||
>
|
||||
<div class="logo-container">
|
||||
<img src="/vapora.svg" alt="Vapora - Development Orchestration" />
|
||||
</div>
|
||||
<p class="tagline">Evaporate complexity</p>
|
||||
<h1
|
||||
data-en="Development Flows<br>When Teams and AI Orchestrate"
|
||||
data-es="El Desarrollo Fluye<br>Cuando Equipos e IA Orquestan"
|
||||
>
|
||||
Development Flows
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
<span
|
||||
class="highlight"
|
||||
data-en="Specialized agents"
|
||||
data-es="Agentes especializados"
|
||||
>Specialized agents</span
|
||||
>
|
||||
<span
|
||||
data-en="orchestrate pipelines for design, implementation, testing, documentation and deployment. Agents learn from history and optimize costs automatically."
|
||||
data-es="orquestan pipelines para diseño, implementación, testing, documentación y deployment. Los agentes aprenden del historial y optimizan costos automáticamente."
|
||||
>orchestrate pipelines for design, implementation, testing,
|
||||
documentation and deployment. Agents learn from history and optimize
|
||||
costs automatically.</span
|
||||
>
|
||||
<strong data-en="100% self-hosted." data-es="100% self-hosted."
|
||||
>100% self-hosted.</strong
|
||||
>
|
||||
<span data-en="" data-es=""></span>
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">
|
||||
<span
|
||||
data-en="The 4 Problems It Solves"
|
||||
data-es="Los 4 Problemas que Resuelve"
|
||||
>The 4 Problems It Solves</span
|
||||
>
|
||||
</h2>
|
||||
<div class="problems-grid">
|
||||
<div class="problem-card">
|
||||
<div class="problem-number">01</div>
|
||||
<h3 data-en="Context Switching" data-es="Cambio de Contexto">
|
||||
Context Switching
|
||||
</h3>
|
||||
<p
|
||||
data-en="Developers jump between tools constantly. Vapora unifies everything in one intelligent system where context flows."
|
||||
data-es="Los developers saltan constantemente entre herramientas. Vapora unifica todo en un sistema inteligente donde el contexto fluye."
|
||||
>
|
||||
Developers jump between tools constantly. Vapora unifies
|
||||
everything in one intelligent system where context flows.
|
||||
</p>
|
||||
</div>
|
||||
<div class="problem-card">
|
||||
<div class="problem-number">02</div>
|
||||
<h3
|
||||
data-en="Knowledge Fragmentation"
|
||||
data-es="Fragmentación de Conocimiento"
|
||||
>
|
||||
Knowledge Fragmentation
|
||||
</h3>
|
||||
<p
|
||||
data-en="Decisions lost in threads, code scattered, docs unmaintained. RAG search and semantic indexing make knowledge discoverable."
|
||||
data-es="Decisiones perdidas en threads, código disperso, docs desactualizadas. Búsqueda RAG e indexing semántico hacen el conocimiento visible."
|
||||
>
|
||||
Decisions lost in threads, code scattered, docs unmaintained. RAG
|
||||
search and semantic indexing make knowledge discoverable.
|
||||
</p>
|
||||
</div>
|
||||
<div class="problem-card">
|
||||
<div class="problem-number">03</div>
|
||||
<h3 data-en="Manual Coordination" data-es="Coordinación Manual">
|
||||
Manual Coordination
|
||||
</h3>
|
||||
<p
|
||||
data-en="Orchestrating code review, testing, documentation and deployment manually creates bottlenecks. Multi-agent workflows solve this."
|
||||
data-es="Orquestar manualmente code review, testing, documentación y deployment crea cuellos. Los workflows multi-agente lo resuelven."
|
||||
>
|
||||
Orchestrating code review, testing, documentation and deployment
|
||||
manually creates bottlenecks. Multi-agent workflows solve this.
|
||||
</p>
|
||||
</div>
|
||||
<div class="problem-card">
|
||||
<div class="problem-number">04</div>
|
||||
<h3 data-en="Dev-Ops Friction" data-es="Fricción Dev-Ops">
|
||||
Dev-Ops Friction
|
||||
</h3>
|
||||
<p
|
||||
data-en="Handoffs between developers and operations lack visibility and context. Vapora maintains unified deployment readiness."
|
||||
data-es="Los handoffs entre developers y operaciones carecen de visibilidad y contexto. Vapora mantiene unificada la deployment readiness."
|
||||
>
|
||||
Handoffs between developers and operations lack visibility and
|
||||
context. Vapora maintains unified deployment readiness.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">
|
||||
<span data-en="How It Works" data-es="Cómo Funciona"
|
||||
>How It Works</span
|
||||
>
|
||||
</h2>
|
||||
<div class="features-grid">
|
||||
<div class="feature-box">
|
||||
<div class="feature-icon">🤖</div>
|
||||
<h3
|
||||
class="feature-title"
|
||||
data-en="Specialized Agents"
|
||||
data-es="Agentes Especializados"
|
||||
>
|
||||
Specialized Agents
|
||||
</h3>
|
||||
<p
|
||||
class="feature-text"
|
||||
data-en="Customizable agents for every role: architecture, development, testing, documentation, deployment and more. Agents learn from execution history with recency bias for continuous improvement."
|
||||
data-es="Agentes customizables para cada rol: arquitectura, desarrollo, testing, documentación, deployment y más. Los agentes aprenden del historial de ejecución con sesgo de recencia para mejora continua."
|
||||
>
|
||||
Customizable agents for every role: architecture, development,
|
||||
testing, documentation, deployment and more. Agents learn from
|
||||
execution history with recency bias for continuous improvement.
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-box" style="border-left-color: #a855f7">
|
||||
<div class="feature-icon">🧠</div>
|
||||
<h3
|
||||
class="feature-title"
|
||||
style="color: #a855f7"
|
||||
data-en="Intelligent Orchestration"
|
||||
data-es="Orquestación Inteligente"
|
||||
>
|
||||
Intelligent Orchestration
|
||||
</h3>
|
||||
<p
|
||||
class="feature-text"
|
||||
data-en="Agents coordinate automatically based on dependencies, context and expertise. Learning-based selection improves over time. Budget enforcement with automatic fallback ensures cost control."
|
||||
data-es="Los agentes se coordinan automáticamente basados en dependencias, contexto y expertise. La selección basada en aprendizaje mejora con el tiempo. La aplicación de presupuestos con fallback automático garantiza el control de costos."
|
||||
>
|
||||
Agents coordinate automatically based on dependencies, context and
|
||||
expertise. Learning-based selection improves over time. Budget
|
||||
enforcement with automatic fallback ensures cost control.
|
||||
</p>
|
||||
</div>
|
||||
<div class="feature-box" style="border-left-color: #ec4899">
|
||||
<div class="feature-icon">☸️</div>
|
||||
<h3
|
||||
class="feature-title"
|
||||
style="color: #ec4899"
|
||||
data-en="Cloud-Native & Self-Hosted"
|
||||
data-es="Cloud-Native y Self-Hosted"
|
||||
>
|
||||
Cloud-Native & Self-Hosted
|
||||
</h3>
|
||||
<p
|
||||
class="feature-text"
|
||||
data-en="Deploy to any Kubernetes cluster (EKS, GKE, AKS, vanilla K8s). Local Docker Compose development. Zero vendor lock-in."
|
||||
data-es="Despliega en cualquier cluster Kubernetes (EKS, GKE, AKS, vanilla K8s). Desarrollo local con Docker Compose. Sin vendor lock-in."
|
||||
>
|
||||
Deploy to any Kubernetes cluster (EKS, GKE, AKS, vanilla K8s).
|
||||
Local Docker Compose development. Zero vendor lock-in.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">
|
||||
<span data-en="Technology Stack" data-es="Stack Tecnológico"
|
||||
>Technology Stack</span
|
||||
>
|
||||
</h2>
|
||||
<div class="tech-stack">
|
||||
<span class="tech-badge">Rust</span>
|
||||
<span class="tech-badge">Axum</span>
|
||||
<span class="tech-badge">SurrealDB</span>
|
||||
<span class="tech-badge">NATS JetStream</span>
|
||||
<span class="tech-badge">Leptos WASM</span>
|
||||
<span class="tech-badge">Kubernetes</span>
|
||||
<span class="tech-badge">Prometheus</span>
|
||||
<span class="tech-badge">Grafana</span>
|
||||
<span class="tech-badge">Knowledge Graph</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h2 class="section-title">
|
||||
<span data-en="Available Agents" data-es="Agentes Disponibles"
|
||||
>Available Agents</span
|
||||
>
|
||||
</h2>
|
||||
<div class="agents-grid">
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Architect" data-es="Architect"
|
||||
>Architect</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="System design"
|
||||
data-es="Diseño de sistemas"
|
||||
>System design</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Developer" data-es="Developer"
|
||||
>Developer</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Code implementation"
|
||||
data-es="Implementación de código"
|
||||
>Code implementation</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span
|
||||
class="agent-name"
|
||||
data-en="CodeReviewer"
|
||||
data-es="CodeReviewer"
|
||||
>CodeReviewer</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Quality assurance"
|
||||
data-es="Aseguramiento de calidad"
|
||||
>Quality assurance</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Tester" data-es="Tester"
|
||||
>Tester</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Tests & benchmarks"
|
||||
data-es="Tests y benchmarks"
|
||||
>Tests & benchmarks</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Documenter" data-es="Documenter"
|
||||
>Documenter</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Documentation"
|
||||
data-es="Documentación"
|
||||
>Documentation</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Marketer" data-es="Marketer"
|
||||
>Marketer</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Marketing content"
|
||||
data-es="Contenido marketing"
|
||||
>Marketing content</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Presenter" data-es="Presenter"
|
||||
>Presenter</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Presentations"
|
||||
data-es="Presentaciones"
|
||||
>Presentations</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="DevOps" data-es="DevOps"
|
||||
>DevOps</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="CI/CD deployment"
|
||||
data-es="Despliegue CI/CD"
|
||||
>CI/CD deployment</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Monitor" data-es="Monitor"
|
||||
>Monitor</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Health & alerting"
|
||||
data-es="Salud y alerting"
|
||||
>Health & alerting</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span class="agent-name" data-en="Security" data-es="Security"
|
||||
>Security</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Audit & compliance"
|
||||
data-es="Auditoría y compliance"
|
||||
>Audit & compliance</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span
|
||||
class="agent-name"
|
||||
data-en="ProjectManager"
|
||||
data-es="ProjectManager"
|
||||
>ProjectManager</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Roadmap tracking"
|
||||
data-es="Tracking de roadmap"
|
||||
>Roadmap tracking</span
|
||||
>
|
||||
</div>
|
||||
<div class="agent-item">
|
||||
<span
|
||||
class="agent-name"
|
||||
data-en="DecisionMaker"
|
||||
data-es="DecisionMaker"
|
||||
>DecisionMaker</span
|
||||
><span
|
||||
class="agent-role"
|
||||
data-en="Conflict resolution"
|
||||
data-es="Resolución de conflictos"
|
||||
>Conflict resolution</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="cta-section">
|
||||
<h2
|
||||
class="cta-title"
|
||||
data-en="Ready for intelligent orchestration?"
|
||||
data-es="¿Listo para la orquestación inteligente?"
|
||||
>
|
||||
Ready for intelligent orchestration?
|
||||
</h2>
|
||||
<p
|
||||
style="color: #94a3b8; margin-bottom: 2rem; font-size: 1.05rem"
|
||||
data-en="Built with Rust 🦀 | Open Source | Self-Hosted"
|
||||
data-es="Construido con Rust 🦀 | Open Source | Self-Hosted"
|
||||
>
|
||||
Built with Rust 🦀 | Open Source | Self-Hosted
|
||||
</p>
|
||||
<a
|
||||
href="https://github.com/vapora-platform/vapora"
|
||||
class="cta-button"
|
||||
data-en="Explore on GitHub →"
|
||||
data-es="Explorar en GitHub →"
|
||||
>Explore on GitHub →</a
|
||||
>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p data-en="Vapora v1.2.0" data-es="Vapora v1.2.0">Vapora v1.2.0</p>
|
||||
<p
|
||||
data-en="Made with Vapora dreams and Rust reality ✨"
|
||||
data-es="Hecho con sueños Vapora y realidad Rust ✨"
|
||||
>
|
||||
Made with Vapora dreams and Rust reality ✨
|
||||
</p>
|
||||
<p
|
||||
style="margin-top: 1rem; font-size: 0.8rem"
|
||||
data-en="Intelligent Development Orchestration | Multi-Agent Multi-IA Platform"
|
||||
data-es="Orquestación Inteligente de Desarrollo | Plataforma Multi-Agente Multi-IA"
|
||||
>
|
||||
Intelligent Development Orchestration | Multi-Agent Multi-IA Platform
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Language management
|
||||
const LANG_KEY = "vapora-lang";
|
||||
|
||||
function getCurrentLanguage() {
|
||||
return localStorage.getItem(LANG_KEY) || "en";
|
||||
}
|
||||
|
||||
function switchLanguage(lang) {
|
||||
localStorage.setItem(LANG_KEY, lang);
|
||||
|
||||
// Update language buttons
|
||||
document.querySelectorAll(".lang-btn").forEach((btn) => {
|
||||
btn.classList.remove("active");
|
||||
if (btn.dataset.lang === lang) {
|
||||
btn.classList.add("active");
|
||||
}
|
||||
});
|
||||
|
||||
// Update all translatable elements
|
||||
document.querySelectorAll("[data-en][data-es]").forEach((el) => {
|
||||
const content = el.dataset[lang];
|
||||
// Use innerHTML for headings that might contain <br>, textContent for others
|
||||
if (
|
||||
el.tagName === "H1" ||
|
||||
el.tagName === "H2" ||
|
||||
el.tagName === "H3"
|
||||
) {
|
||||
el.innerHTML = content;
|
||||
} else {
|
||||
el.textContent = content;
|
||||
}
|
||||
});
|
||||
|
||||
document.documentElement.lang = lang;
|
||||
}
|
||||
|
||||
// Initialize language on page load
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const currentLang = getCurrentLanguage();
|
||||
switchLanguage(currentLang);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
200
assets/web/src/vapora.svg
Normal file
200
assets/web/src/vapora.svg
Normal file
@ -0,0 +1,200 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="170 40 590 300" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||
<defs>
|
||||
<!-- Google Fonts import -->
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@800&display=swap');
|
||||
</style>
|
||||
|
||||
<!-- Gradiente principal -->
|
||||
<linearGradient id="techGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:1"/>
|
||||
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:1"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Gradiente vertical -->
|
||||
<linearGradient id="vertGrad" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:0.8"/>
|
||||
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:0.4"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Filtro glow tech -->
|
||||
<filter id="techGlow">
|
||||
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- Filtro glow fuerte -->
|
||||
<filter id="strongGlow">
|
||||
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- Filtro glass -->
|
||||
<filter id="glass">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="0.5" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo"/>
|
||||
<feBlend in="SourceGraphic" in2="goo"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- Fondo -->
|
||||
<rect width="800" height="400" fill="#000000"/>
|
||||
|
||||
<!-- Grid de fondo técnico sutil -->
|
||||
<g opacity="0.08" stroke="#22d3ee" stroke-width="1">
|
||||
<line x1="0" y1="133" x2="800" y2="133"/>
|
||||
<line x1="0" y1="200" x2="800" y2="200"/>
|
||||
<line x1="0" y1="267" x2="800" y2="267"/>
|
||||
<line x1="133" y1="0" x2="133" y2="400"/>
|
||||
<line x1="267" y1="0" x2="267" y2="400"/>
|
||||
<line x1="400" y1="0" x2="400" y2="400"/>
|
||||
<line x1="533" y1="0" x2="533" y2="400"/>
|
||||
<line x1="667" y1="0" x2="667" y2="400"/>
|
||||
</g>
|
||||
|
||||
<!-- Símbolo técnico: flujo de datos ascendente -->
|
||||
<g transform="translate(267, 280)">
|
||||
<!-- Base: plataforma -->
|
||||
<rect x="-25" y="0" width="50" height="6.67" fill="url(#techGrad)" opacity="0.8" rx="3.33"/>
|
||||
|
||||
<!-- Stream principal - línea central tipo señal -->
|
||||
<path d="M 0 0 L 0 -50 L 8.33 -58 L -8.33 -75 L 8.33 -92 L -8.33 -108 L 8.33 -125 L 0 -133 L 0 -200" stroke="url(#vertGrad)" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,500;500,0;0,500" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0.8;1;0.8" dur="2s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream izquierdo 1 -->
|
||||
<path d="M -33 0 L -33 -42 L -30 -58 L -37 -75 L -30 -92 L -37 -108 L -33 -125 L -33 -167" stroke="#22d3ee" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,417;417,0;0,417" dur="4.5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream izquierdo 2 -->
|
||||
<path d="M -58 0 L -58 -33 L -53 -50 L -63 -67 L -53 -83 L -63 -100 L -58 -117 L -58 -142" stroke="#a855f7" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5">
|
||||
<animate attributeName="stroke-dasharray" values="0,333;333,0;0,333" dur="5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream derecho 1 -->
|
||||
<path d="M 33 0 L 33 -42 L 30 -58 L 37 -75 L 30 -92 L 37 -108 L 33 -125 L 33 -167" stroke="#ec4899" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,417;417,0;0,417" dur="4.2s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream derecho 2 -->
|
||||
<path d="M 58 0 L 58 -33 L 53 -50 L 63 -67 L 53 -83 L 63 -100 L 58 -117 L 58 -142" stroke="#22d3ee" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5">
|
||||
<animate attributeName="stroke-dasharray" values="0,333;333,0;0,333" dur="5.5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Nodos de datos en el flujo principal -->
|
||||
<circle cx="0" cy="-67" r="5" fill="#22d3ee" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-67;-183;-67" dur="3s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="3s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="0" cy="-100" r="4.17" fill="#a855f7" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-100;-217;-100" dur="3.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="3.5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="0" cy="-133" r="3.33" fill="#ec4899" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-133;-233;-133" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="4s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<!-- Partículas laterales -->
|
||||
<circle cx="-33" cy="-83" r="3.33" fill="#22d3ee" opacity="0.7">
|
||||
<animate attributeName="cy" values="-83;-175;-83" dur="3.8s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.7;0" dur="3.8s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="33" cy="-92" r="3.33" fill="#ec4899" opacity="0.7">
|
||||
<animate attributeName="cy" values="-92;-175;-92" dur="4.2s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.7;0" dur="4.2s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="-58" cy="-58" r="2.5" fill="#a855f7" opacity="0.5">
|
||||
<animate attributeName="cy" values="-58;-142;-58" dur="4.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="4.5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="58" cy="-67" r="2.5" fill="#22d3ee" opacity="0.5">
|
||||
<animate attributeName="cy" values="-67;-142;-67" dur="5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<!-- Hexágonos técnicos flotantes -->
|
||||
<polygon points="0,-158 5,-162 5,-167 0,-170 -5,-167 -5,-162" stroke="#22d3ee" fill="none" stroke-width="1.67" opacity="0.6">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-50);translate(0,0)" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.6;0" dur="4s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<polygon points="-42,-117 -37,-120 -37,-125 -42,-128 -47,-125 -47,-120" stroke="#a855f7" fill="none" stroke-width="1.67" opacity="0.5">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-42);translate(0,0)" dur="4.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="4.5s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<polygon points="42,-125 47,-128 47,-133 42,-137 37,-133 37,-128" stroke="#ec4899" fill="none" stroke-width="1.67" opacity="0.5">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-33);translate(0,0)" dur="5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="5s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<!-- Líneas de conexión horizontales animadas -->
|
||||
<line x1="-33" y1="-100" x2="-8" y2="-100" stroke="#22d3ee" stroke-width="0.83" opacity="0.4">
|
||||
<animate attributeName="opacity" values="0;0.4;0" dur="2s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="8" y1="-117" x2="33" y2="-117" stroke="#ec4899" stroke-width="0.83" opacity="0.4">
|
||||
<animate attributeName="opacity" values="0;0.4;0" dur="2.5s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="-58" y1="-83" x2="-37" y2="-83" stroke="#a855f7" stroke-width="0.83" opacity="0.3">
|
||||
<animate attributeName="opacity" values="0;0.3;0" dur="3s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="37" y1="-92" x2="58" y2="-92" stroke="#22d3ee" stroke-width="0.83" opacity="0.3">
|
||||
<animate attributeName="opacity" values="0;0.3;0" dur="3.5s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
</g>
|
||||
|
||||
<!-- Texto VAPORA -->
|
||||
<g filter="url(#glass)">
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGrad)" letter-spacing="5" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="none" stroke="rgba(255,255,255,0.2)" stroke-width="0.83" letter-spacing="5" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
</g>
|
||||
|
||||
<!-- Glow en texto -->
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGrad)" letter-spacing="5" filter="url(#techGlow)" opacity="0.3" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
|
||||
<!-- Tagline -->
|
||||
<text x="550" y="240" font-family="'Inter', sans-serif" font-size="20" fill="#a855f7" opacity="0.8" letter-spacing="0.25em" text-anchor="middle">
|
||||
Evaporate complexity
|
||||
</text>
|
||||
|
||||
<!-- Indicador técnico decorativo -->
|
||||
<g transform="translate(550, 280)">
|
||||
<rect x="0" y="0" width="2" height="13.33" fill="#22d3ee" opacity="0.6">
|
||||
<animate attributeName="height" values="13.33;20;13.33" dur="1.5s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
<rect x="6.67" y="0" width="2" height="16.67" fill="#a855f7" opacity="0.6">
|
||||
<animate attributeName="height" values="16.67;23.33;16.67" dur="1.8s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
<rect x="13.33" y="0" width="2" height="10" fill="#ec4899" opacity="0.6">
|
||||
<animate attributeName="height" values="10;16.67;10" dur="1.3s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
200
assets/web/vapora.svg
Normal file
200
assets/web/vapora.svg
Normal file
@ -0,0 +1,200 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="170 40 590 300" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
|
||||
<defs>
|
||||
<!-- Google Fonts import -->
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@800&display=swap');
|
||||
</style>
|
||||
|
||||
<!-- Gradiente principal -->
|
||||
<linearGradient id="techGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:1"/>
|
||||
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:1"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Gradiente vertical -->
|
||||
<linearGradient id="vertGrad" x1="0%" y1="100%" x2="0%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#22d3ee;stop-opacity:1"/>
|
||||
<stop offset="50%" style="stop-color:#a855f7;stop-opacity:0.8"/>
|
||||
<stop offset="100%" style="stop-color:#ec4899;stop-opacity:0.4"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Filtro glow tech -->
|
||||
<filter id="techGlow">
|
||||
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- Filtro glow fuerte -->
|
||||
<filter id="strongGlow">
|
||||
<feGaussianBlur stdDeviation="4" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- Filtro glass -->
|
||||
<filter id="glass">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="0.5" result="blur"/>
|
||||
<feColorMatrix in="blur" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo"/>
|
||||
<feBlend in="SourceGraphic" in2="goo"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- Fondo -->
|
||||
<rect width="800" height="400" fill="#000000"/>
|
||||
|
||||
<!-- Grid de fondo técnico sutil -->
|
||||
<g opacity="0.08" stroke="#22d3ee" stroke-width="1">
|
||||
<line x1="0" y1="133" x2="800" y2="133"/>
|
||||
<line x1="0" y1="200" x2="800" y2="200"/>
|
||||
<line x1="0" y1="267" x2="800" y2="267"/>
|
||||
<line x1="133" y1="0" x2="133" y2="400"/>
|
||||
<line x1="267" y1="0" x2="267" y2="400"/>
|
||||
<line x1="400" y1="0" x2="400" y2="400"/>
|
||||
<line x1="533" y1="0" x2="533" y2="400"/>
|
||||
<line x1="667" y1="0" x2="667" y2="400"/>
|
||||
</g>
|
||||
|
||||
<!-- Símbolo técnico: flujo de datos ascendente -->
|
||||
<g transform="translate(267, 280)">
|
||||
<!-- Base: plataforma -->
|
||||
<rect x="-25" y="0" width="50" height="6.67" fill="url(#techGrad)" opacity="0.8" rx="3.33"/>
|
||||
|
||||
<!-- Stream principal - línea central tipo señal -->
|
||||
<path d="M 0 0 L 0 -50 L 8.33 -58 L -8.33 -75 L 8.33 -92 L -8.33 -108 L 8.33 -125 L 0 -133 L 0 -200" stroke="url(#vertGrad)" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,500;500,0;0,500" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0.8;1;0.8" dur="2s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream izquierdo 1 -->
|
||||
<path d="M -33 0 L -33 -42 L -30 -58 L -37 -75 L -30 -92 L -37 -108 L -33 -125 L -33 -167" stroke="#22d3ee" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,417;417,0;0,417" dur="4.5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream izquierdo 2 -->
|
||||
<path d="M -58 0 L -58 -33 L -53 -50 L -63 -67 L -53 -83 L -63 -100 L -58 -117 L -58 -142" stroke="#a855f7" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5">
|
||||
<animate attributeName="stroke-dasharray" values="0,333;333,0;0,333" dur="5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream derecho 1 -->
|
||||
<path d="M 33 0 L 33 -42 L 30 -58 L 37 -75 L 30 -92 L 37 -108 L 33 -125 L 33 -167" stroke="#ec4899" stroke-width="3.33" fill="none" stroke-linecap="round" opacity="0.6" filter="url(#techGlow)">
|
||||
<animate attributeName="stroke-dasharray" values="0,417;417,0;0,417" dur="4.2s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Stream derecho 2 -->
|
||||
<path d="M 58 0 L 58 -33 L 53 -50 L 63 -67 L 53 -83 L 63 -100 L 58 -117 L 58 -142" stroke="#22d3ee" stroke-width="2.5" fill="none" stroke-linecap="round" opacity="0.5">
|
||||
<animate attributeName="stroke-dasharray" values="0,333;333,0;0,333" dur="5.5s" repeatCount="indefinite"/>
|
||||
</path>
|
||||
|
||||
<!-- Nodos de datos en el flujo principal -->
|
||||
<circle cx="0" cy="-67" r="5" fill="#22d3ee" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-67;-183;-67" dur="3s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="3s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="0" cy="-100" r="4.17" fill="#a855f7" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-100;-217;-100" dur="3.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="3.5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="0" cy="-133" r="3.33" fill="#ec4899" filter="url(#strongGlow)">
|
||||
<animate attributeName="cy" values="-133;-233;-133" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;1;0" dur="4s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<!-- Partículas laterales -->
|
||||
<circle cx="-33" cy="-83" r="3.33" fill="#22d3ee" opacity="0.7">
|
||||
<animate attributeName="cy" values="-83;-175;-83" dur="3.8s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.7;0" dur="3.8s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="33" cy="-92" r="3.33" fill="#ec4899" opacity="0.7">
|
||||
<animate attributeName="cy" values="-92;-175;-92" dur="4.2s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.7;0" dur="4.2s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="-58" cy="-58" r="2.5" fill="#a855f7" opacity="0.5">
|
||||
<animate attributeName="cy" values="-58;-142;-58" dur="4.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="4.5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<circle cx="58" cy="-67" r="2.5" fill="#22d3ee" opacity="0.5">
|
||||
<animate attributeName="cy" values="-67;-142;-67" dur="5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="5s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
|
||||
<!-- Hexágonos técnicos flotantes -->
|
||||
<polygon points="0,-158 5,-162 5,-167 0,-170 -5,-167 -5,-162" stroke="#22d3ee" fill="none" stroke-width="1.67" opacity="0.6">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-50);translate(0,0)" dur="4s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.6;0" dur="4s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<polygon points="-42,-117 -37,-120 -37,-125 -42,-128 -47,-125 -47,-120" stroke="#a855f7" fill="none" stroke-width="1.67" opacity="0.5">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-42);translate(0,0)" dur="4.5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="4.5s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<polygon points="42,-125 47,-128 47,-133 42,-137 37,-133 37,-128" stroke="#ec4899" fill="none" stroke-width="1.67" opacity="0.5">
|
||||
<animate attributeName="transform" values="translate(0,0);translate(0,-33);translate(0,0)" dur="5s" repeatCount="indefinite"/>
|
||||
<animate attributeName="opacity" values="0;0.5;0" dur="5s" repeatCount="indefinite"/>
|
||||
</polygon>
|
||||
|
||||
<!-- Líneas de conexión horizontales animadas -->
|
||||
<line x1="-33" y1="-100" x2="-8" y2="-100" stroke="#22d3ee" stroke-width="0.83" opacity="0.4">
|
||||
<animate attributeName="opacity" values="0;0.4;0" dur="2s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="8" y1="-117" x2="33" y2="-117" stroke="#ec4899" stroke-width="0.83" opacity="0.4">
|
||||
<animate attributeName="opacity" values="0;0.4;0" dur="2.5s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="-58" y1="-83" x2="-37" y2="-83" stroke="#a855f7" stroke-width="0.83" opacity="0.3">
|
||||
<animate attributeName="opacity" values="0;0.3;0" dur="3s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
|
||||
<line x1="37" y1="-92" x2="58" y2="-92" stroke="#22d3ee" stroke-width="0.83" opacity="0.3">
|
||||
<animate attributeName="opacity" values="0;0.3;0" dur="3.5s" repeatCount="indefinite"/>
|
||||
</line>
|
||||
</g>
|
||||
|
||||
<!-- Texto VAPORA -->
|
||||
<g filter="url(#glass)">
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGrad)" letter-spacing="5" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="none" stroke="rgba(255,255,255,0.2)" stroke-width="0.83" letter-spacing="5" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
</g>
|
||||
|
||||
<!-- Glow en texto -->
|
||||
<text x="550" y="207" font-family="'JetBrains Mono', 'Fira Code', monospace" font-size="90" font-weight="800" fill="url(#techGrad)" letter-spacing="5" filter="url(#techGlow)" opacity="0.3" text-anchor="middle">
|
||||
VAPORA
|
||||
</text>
|
||||
|
||||
<!-- Tagline -->
|
||||
<text x="550" y="240" font-family="'Inter', sans-serif" font-size="20" fill="#a855f7" opacity="0.8" letter-spacing="0.25em" text-anchor="middle">
|
||||
Evaporate complexity
|
||||
</text>
|
||||
|
||||
<!-- Indicador técnico decorativo -->
|
||||
<g transform="translate(550, 280)">
|
||||
<rect x="0" y="0" width="2" height="13.33" fill="#22d3ee" opacity="0.6">
|
||||
<animate attributeName="height" values="13.33;20;13.33" dur="1.5s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
<rect x="6.67" y="0" width="2" height="16.67" fill="#a855f7" opacity="0.6">
|
||||
<animate attributeName="height" values="16.67;23.33;16.67" dur="1.8s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
<rect x="13.33" y="0" width="2" height="10" fill="#ec4899" opacity="0.6">
|
||||
<animate attributeName="height" values="10;16.67;10" dur="1.3s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
Loading…
x
Reference in New Issue
Block a user