Really-amin commited on
Commit
0cf66ca
·
verified ·
1 Parent(s): 7c87577

Upload 1042 files

Browse files
.dockerignore CHANGED
@@ -4,6 +4,9 @@ __pycache__/
4
  *$py.class
5
  *.so
6
  .Python
 
 
 
7
  build/
8
  develop-eggs/
9
  dist/
@@ -19,15 +22,11 @@ wheels/
19
  *.egg-info/
20
  .installed.cfg
21
  *.egg
22
- MANIFEST
23
- pip-log.txt
24
- pip-delete-this-directory.txt
25
 
26
  # Virtual environments
 
27
  venv/
28
  ENV/
29
- env/
30
- .venv
31
 
32
  # IDE
33
  .vscode/
@@ -35,87 +34,54 @@ env/
35
  *.swp
36
  *.swo
37
  *~
 
 
38
  .DS_Store
 
 
39
 
40
  # Git
41
  .git/
42
  .gitignore
43
  .gitattributes
44
 
45
- # Documentation
46
- *.md
47
- docs/
48
- README*.md
49
- CHANGELOG.md
50
- LICENSE
51
-
52
  # Testing
53
  .pytest_cache/
54
  .coverage
55
  htmlcov/
56
  .tox/
57
- .hypothesis/
58
- tests/
59
- test_*.py
60
 
61
- # Logs and databases (will be created in container)
 
 
 
 
62
  *.log
63
  logs/
64
- data/*.db
65
- data/*.sqlite
66
- data/*.db-journal
67
-
68
- # Environment files (should be set via docker-compose or HF Secrets)
69
- .env
70
- .env.*
71
- !.env.example
72
-
73
- # Docker
74
- docker-compose*.yml
75
- !docker-compose.yml
76
- Dockerfile
77
- .dockerignore
78
-
79
- # CI/CD
80
- .github/
81
- .gitlab-ci.yml
82
- .travis.yml
83
- azure-pipelines.yml
84
 
85
  # Temporary files
86
  *.tmp
87
  *.bak
88
- *.swp
89
- temp/
90
- tmp/
91
 
92
  # Node modules (if any)
93
  node_modules/
94
- package-lock.json
95
- yarn.lock
96
-
97
- # OS files
98
- Thumbs.db
99
- .DS_Store
100
- desktop.ini
101
 
102
- # Jupyter notebooks
103
- .ipynb_checkpoints/
104
- *.ipynb
 
105
 
106
- # Model cache (models will be downloaded in container)
107
- models/
108
- .cache/
109
- .huggingface/
110
 
111
- # Large files that shouldn't be in image
112
- *.tar
113
- *.tar.gz
114
- *.zip
115
- *.rar
116
- *.7z
117
 
118
- # Screenshots and assets not needed
119
- screenshots/
120
- assets/*.png
121
- assets/*.jpg
 
4
  *$py.class
5
  *.so
6
  .Python
7
+ env/
8
+ venv/
9
+ ENV/
10
  build/
11
  develop-eggs/
12
  dist/
 
22
  *.egg-info/
23
  .installed.cfg
24
  *.egg
 
 
 
25
 
26
  # Virtual environments
27
+ .venv
28
  venv/
29
  ENV/
 
 
30
 
31
  # IDE
32
  .vscode/
 
34
  *.swp
35
  *.swo
36
  *~
37
+
38
+ # OS
39
  .DS_Store
40
+ Thumbs.db
41
+ desktop.ini
42
 
43
  # Git
44
  .git/
45
  .gitignore
46
  .gitattributes
47
 
 
 
 
 
 
 
 
48
  # Testing
49
  .pytest_cache/
50
  .coverage
51
  htmlcov/
52
  .tox/
 
 
 
53
 
54
+ # Documentation (optional - remove if you want docs in image)
55
+ *.md
56
+ docs/
57
+
58
+ # Logs
59
  *.log
60
  logs/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  # Temporary files
63
  *.tmp
64
  *.bak
65
+ *.cache
 
 
66
 
67
  # Node modules (if any)
68
  node_modules/
69
+ npm-debug.log
 
 
 
 
 
 
70
 
71
+ # Environment files (security)
72
+ .env
73
+ .env.local
74
+ .env.*.local
75
 
76
+ # Docker
77
+ Dockerfile
78
+ .dockerignore
79
+ docker-compose.yml
80
 
81
+ # CI/CD
82
+ .github/
83
+ .gitlab-ci.yml
 
 
 
84
 
85
+ # Other
86
+ *.sqlite
87
+ *.db
 
.gitignore CHANGED
@@ -1,15 +1,12 @@
1
- # API Keys
2
- .env
3
- .env.production
4
- .env.local
5
- *.key
6
-
7
  # Python
8
  __pycache__/
9
  *.py[cod]
10
  *$py.class
11
  *.so
12
  .Python
 
 
 
13
  build/
14
  develop-eggs/
15
  dist/
@@ -22,11 +19,15 @@ parts/
22
  sdist/
23
  var/
24
  wheels/
 
 
25
  *.egg-info/
26
  .installed.cfg
27
  *.egg
 
28
 
29
  # Virtual Environment
 
30
  venv/
31
  ENV/
32
  env/
@@ -37,20 +38,100 @@ env/
37
  *.swp
38
  *.swo
39
  *~
 
 
 
40
 
41
  # OS
42
  .DS_Store
 
 
 
 
 
43
  Thumbs.db
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  # Logs
46
  *.log
47
  logs/
 
 
48
 
49
  # Database
50
- *.db
51
  *.sqlite
52
  *.sqlite3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- # Data
55
- data/database/
56
- data/exports/
 
 
 
 
 
 
 
1
  # Python
2
  __pycache__/
3
  *.py[cod]
4
  *$py.class
5
  *.so
6
  .Python
7
+ env/
8
+ venv/
9
+ ENV/
10
  build/
11
  develop-eggs/
12
  dist/
 
19
  sdist/
20
  var/
21
  wheels/
22
+ pip-wheel-metadata/
23
+ share/python-wheels/
24
  *.egg-info/
25
  .installed.cfg
26
  *.egg
27
+ MANIFEST
28
 
29
  # Virtual Environment
30
+ .venv
31
  venv/
32
  ENV/
33
  env/
 
38
  *.swp
39
  *.swo
40
  *~
41
+ .project
42
+ .pydevproject
43
+ .settings/
44
 
45
  # OS
46
  .DS_Store
47
+ .DS_Store?
48
+ ._*
49
+ .Spotlight-V100
50
+ .Trashes
51
+ ehthumbs.db
52
  Thumbs.db
53
+ desktop.ini
54
+
55
+ # Testing
56
+ .pytest_cache/
57
+ .coverage
58
+ .coverage.*
59
+ htmlcov/
60
+ .tox/
61
+ .nox/
62
+ coverage.xml
63
+ *.cover
64
+ .hypothesis/
65
 
66
  # Logs
67
  *.log
68
  logs/
69
+ pip-log.txt
70
+ pip-delete-this-directory.txt
71
 
72
  # Database
 
73
  *.sqlite
74
  *.sqlite3
75
+ *.db
76
+
77
+ # Environment
78
+ .env
79
+ .env.local
80
+ .env.*.local
81
+ .envrc
82
+
83
+ # Temporary files
84
+ *.tmp
85
+ *.bak
86
+ *.swp
87
+ *.cache
88
+ *~
89
+
90
+ # Node (if using frontend build tools)
91
+ node_modules/
92
+ npm-debug.log*
93
+ yarn-debug.log*
94
+ yarn-error.log*
95
+ .npm
96
+
97
+ # Distribution
98
+ dist/
99
+ build/
100
+
101
+ # Jupyter Notebook
102
+ .ipynb_checkpoints
103
+ *.ipynb
104
+
105
+ # pyenv
106
+ .python-version
107
+
108
+ # Celery
109
+ celerybeat-schedule
110
+ celerybeat.pid
111
+
112
+ # SageMath
113
+ *.sage.py
114
+
115
+ # Spyder
116
+ .spyderproject
117
+ .spyproject
118
+
119
+ # Rope
120
+ .ropeproject
121
+
122
+ # mkdocs
123
+ /site
124
+
125
+ # mypy
126
+ .mypy_cache/
127
+ .dmypy.json
128
+ dmypy.json
129
+
130
+ # Pyre
131
+ .pyre/
132
+
133
+ # pytype
134
+ .pytype/
135
 
136
+ # Cython
137
+ cython_debug/
 
Dockerfile CHANGED
@@ -1,37 +1,38 @@
 
 
 
1
  FROM python:3.11-slim
2
 
 
3
  WORKDIR /app
4
 
5
- # Install system dependencies
6
- RUN apt-get update && apt-get install -y \
7
- build-essential \
8
- curl \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
- # Copy requirements first for better caching
12
- COPY requirements_hf.txt ./requirements.txt
13
 
14
  # Install Python dependencies
15
- RUN pip install --upgrade pip setuptools wheel && \
16
  pip install --no-cache-dir -r requirements.txt
17
 
18
  # Copy application files
19
  COPY . .
20
 
21
- # Create necessary directories
22
- RUN mkdir -p data/database logs api-resources
23
-
24
  # Set environment variables
25
- ENV PYTHONUNBUFFERED=1
26
  ENV PORT=7860
27
- ENV GRADIO_SERVER_NAME=0.0.0.0
28
- ENV GRADIO_SERVER_PORT=7860
29
- ENV DOCKER_CONTAINER=true
30
- # Default to FastAPI+HTML in Docker (for index.html frontend)
31
- ENV USE_FASTAPI_HTML=true
32
- ENV USE_GRADIO=false
33
 
 
34
  EXPOSE 7860
35
 
36
- # Run the FastAPI application with uvicorn
37
- CMD ["uvicorn", "hf_space_api:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
 
 
 
 
 
1
+ # Dockerfile for Hugging Face Space
2
+ # Optimized for crypto intelligence hub with FastAPI + Flask
3
+
4
  FROM python:3.11-slim
5
 
6
+ # Set working directory
7
  WORKDIR /app
8
 
9
+ # Install system dependencies (minimal for smaller image)
10
+ RUN apt-get update && apt-get install -y --no-install-recommends \
11
+ gcc \
12
+ g++ \
13
  && rm -rf /var/lib/apt/lists/*
14
 
15
+ # Copy requirements first (for better caching)
16
+ COPY requirements.txt .
17
 
18
  # Install Python dependencies
19
+ RUN pip install --no-cache-dir --upgrade pip && \
20
  pip install --no-cache-dir -r requirements.txt
21
 
22
  # Copy application files
23
  COPY . .
24
 
 
 
 
25
  # Set environment variables
 
26
  ENV PORT=7860
27
+ ENV PYTHONUNBUFFERED=1
28
+ ENV HF_MODE=public
 
 
 
 
29
 
30
+ # Expose port
31
  EXPOSE 7860
32
 
33
+ # Health check
34
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
35
+ CMD python -c "import requests; requests.get('http://localhost:7860/api/health')"
36
+
37
+ # Run the application with uvicorn
38
+ CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
example_upload_usage.py ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ مثال استفاده از HuggingFace Upload Manager
4
+ Example usage of HuggingFace Upload Manager with retry and rate limiting
5
+ """
6
+
7
+ import asyncio
8
+ from hf_upload_manager import get_upload_manager, UploadConfig
9
+ from ai_models import (
10
+ upload_dataset_to_hf,
11
+ upload_folder_to_hf,
12
+ batch_upload_datasets_to_hf,
13
+ get_upload_stats
14
+ )
15
+
16
+
17
+ def example_single_file_upload():
18
+ """مثال آپلود یک فایل"""
19
+ print("=" * 60)
20
+ print("مثال 1: آپلود یک فایل به HuggingFace")
21
+ print("Example 1: Upload single file to HuggingFace")
22
+ print("=" * 60)
23
+
24
+ # داده‌های نمونه
25
+ sample_data = {
26
+ "crypto_data": [
27
+ {"symbol": "BTC", "price": 45000, "volume": 1000000},
28
+ {"symbol": "ETH", "price": 3000, "volume": 500000}
29
+ ],
30
+ "timestamp": "2025-12-06T12:00:00Z"
31
+ }
32
+
33
+ result = upload_dataset_to_hf(
34
+ data=sample_data,
35
+ repo_id="your-username/your-dataset", # تغییر دهید
36
+ file_name="crypto_prices.json",
37
+ repo_type="dataset",
38
+ commit_message="Update crypto prices"
39
+ )
40
+
41
+ print(f"نتیجه آپلود: {result}")
42
+ print(f"Upload result: {result}")
43
+ print()
44
+
45
+
46
+ def example_folder_upload():
47
+ """مثال آپلود یک فولدر"""
48
+ print("=" * 60)
49
+ print("مثال 2: آپلود یک فولدر به HuggingFace")
50
+ print("Example 2: Upload folder to HuggingFace")
51
+ print("=" * 60)
52
+
53
+ result = upload_folder_to_hf(
54
+ folder_path="./data", # مسیر فولدر خود را وارد کنید
55
+ repo_id="your-username/your-dataset",
56
+ repo_type="dataset",
57
+ path_in_repo="data",
58
+ commit_message="Upload data folder"
59
+ )
60
+
61
+ print(f"نتیجه آپلود فولدر: {result}")
62
+ print(f"Folder upload result: {result}")
63
+ print()
64
+
65
+
66
+ def example_batch_upload():
67
+ """مثال آپلود دسته‌ای (Batch Upload)"""
68
+ print("=" * 60)
69
+ print("مثال 3: آپلود دسته‌ای فایل‌ها")
70
+ print("Example 3: Batch upload files")
71
+ print("=" * 60)
72
+
73
+ # لیست داده‌ها برای آپلود
74
+ datasets = [
75
+ {
76
+ "data": {"coin": "BTC", "price": 45000},
77
+ "file_name": "btc_data.json",
78
+ "commit_message": "Add BTC data"
79
+ },
80
+ {
81
+ "data": {"coin": "ETH", "price": 3000},
82
+ "file_name": "eth_data.json",
83
+ "commit_message": "Add ETH data"
84
+ },
85
+ {
86
+ "data": {"coin": "SOL", "price": 100},
87
+ "file_name": "sol_data.json",
88
+ "commit_message": "Add SOL data"
89
+ }
90
+ ]
91
+
92
+ result = batch_upload_datasets_to_hf(
93
+ datasets=datasets,
94
+ repo_id="your-username/your-dataset",
95
+ repo_type="dataset"
96
+ )
97
+
98
+ print(f"نتیجه آپلود دسته‌ای: {result}")
99
+ print(f"Batch upload result: {result}")
100
+ print(f"تعداد کل: {result.get('total')}")
101
+ print(f"Total: {result.get('total')}")
102
+ print(f"موفق: {result.get('uploaded')}")
103
+ print(f"Success: {result.get('uploaded')}")
104
+ print(f"ناموفق: {result.get('failed')}")
105
+ print(f"Failed: {result.get('failed')}")
106
+ print()
107
+
108
+
109
+ def example_advanced_config():
110
+ """مثال استفاده پیشرفته با تنظیمات سفارشی"""
111
+ print("=" * 60)
112
+ print("مثال 4: استفاده پیشرفته با تنظیمات سفارشی")
113
+ print("Example 4: Advanced usage with custom config")
114
+ print("=" * 60)
115
+
116
+ # تنظیمات سفارشی
117
+ custom_config = UploadConfig(
118
+ max_retries=5, # حداکثر تعداد تلاش مجدد
119
+ base_delay=60, # تأخیر پایه (ثانیه)
120
+ max_delay=1800, # حداکثر تأخیر (30 دقیقه)
121
+ batch_size=10, # تعداد فایل در هر دسته
122
+ rate_limit_delay=120, # تأخیر بعد از خطای 429
123
+ exponential_backoff=True # استفاده از backoff نمایی
124
+ )
125
+
126
+ # ایجاد manager با تنظیمات سفارشی
127
+ manager = get_upload_manager(config=custom_config)
128
+
129
+ # آپلود با تنظیمات سفارشی
130
+ result = manager.upload_file_with_retry(
131
+ path_or_fileobj="sample_data.json",
132
+ path_in_repo="data/sample.json",
133
+ repo_id="your-username/your-dataset",
134
+ repo_type="dataset",
135
+ commit_message="Upload with custom config"
136
+ )
137
+
138
+ print(f"نتیجه با تنظیمات سفارشی: {result}")
139
+ print(f"Result with custom config: {result}")
140
+ print()
141
+
142
+
143
+ def example_check_stats():
144
+ """بررسی آمار آپلود"""
145
+ print("=" * 60)
146
+ print("مثال 5: بررسی آمار آپلود")
147
+ print("Example 5: Check upload statistics")
148
+ print("=" * 60)
149
+
150
+ stats = get_upload_stats()
151
+
152
+ print(f"آمار آپلود:")
153
+ print(f"Upload statistics:")
154
+ print(f" - تعداد کل آپلودها: {stats.get('total_uploads', 0)}")
155
+ print(f" - Total uploads: {stats.get('total_uploads', 0)}")
156
+ print(f" - آخرین زمان آپلود: {stats.get('last_upload_time', 'N/A')}")
157
+ print(f" - Last upload time: {stats.get('last_upload_time', 'N/A')}")
158
+ print(f" - محدودیت نرخ فعال: {stats.get('rate_limited', False)}")
159
+ print(f" - Rate limited: {stats.get('rate_limited', False)}")
160
+
161
+ if stats.get('rate_limited'):
162
+ print(f" - زمان باقیمانده محدودیت: {stats.get('rate_limit_remaining', 0)} ثانیه")
163
+ print(f" - Rate limit remaining: {stats.get('rate_limit_remaining', 0)} seconds")
164
+
165
+ print()
166
+
167
+
168
+ def example_error_handling():
169
+ """مثال مدیریت خطاها"""
170
+ print("=" * 60)
171
+ print("مثال 6: مدیریت خطاها و retry")
172
+ print("Example 6: Error handling and retry")
173
+ print("=" * 60)
174
+
175
+ # این مثال نشان می‌دهد که سیستم خطاها را مدیریت می‌کند
176
+ result = upload_dataset_to_hf(
177
+ data={"test": "data"},
178
+ repo_id="invalid/repo-that-might-fail", # ممکن است با خطا مواجه شود
179
+ file_name="test.json"
180
+ )
181
+
182
+ # بررسی وضعیت
183
+ if result.get('status') == 'success':
184
+ print("✅ آپلود موفقیت‌آمیز بود")
185
+ print("✅ Upload successful")
186
+ print(f"URL: {result.get('url')}")
187
+
188
+ elif result.get('status') == 'rate_limited':
189
+ print("⏳ محدودیت نرخ فعال است")
190
+ print("⏳ Rate limit active")
191
+ print(f"تلاش مجدد بعد از: {result.get('retry_after')} ثانیه")
192
+ print(f"Retry after: {result.get('retry_after')} seconds")
193
+
194
+ elif result.get('status') == 'error':
195
+ print("❌ خطا در آپلود")
196
+ print("❌ Upload error")
197
+ print(f"پیام خطا: {result.get('message')}")
198
+ print(f"Error message: {result.get('message')}")
199
+
200
+ if result.get('error_code') == 429:
201
+ print("محدودیت تعداد درخواست‌ها - لطفاً بعداً تلاش کنید")
202
+ print("Rate limit - please try later")
203
+ elif result.get('error_code') in [401, 403]:
204
+ print("خطای احراز هویت - لطفاً HF_TOKEN را بررسی کنید")
205
+ print("Authentication error - please check HF_TOKEN")
206
+
207
+ print()
208
+
209
+
210
+ def main():
211
+ """اجرای همه مثال‌ها"""
212
+ print("\n" + "=" * 60)
213
+ print("راهنمای استفاده از HuggingFace Upload Manager")
214
+ print("HuggingFace Upload Manager Usage Guide")
215
+ print("=" * 60 + "\n")
216
+
217
+ print("⚠️ توجه: قبل از اجرا باید HF_TOKEN را تنظیم کنید")
218
+ print("⚠️ Note: You need to set HF_TOKEN before running")
219
+ print(" export HF_TOKEN=your_token_here (Linux/Mac)")
220
+ print(" set HF_TOKEN=your_token_here (Windows CMD)")
221
+ print(" $env:HF_TOKEN='your_token_here' (Windows PowerShell)")
222
+ print("\n")
223
+
224
+ # اجرای مثال‌ها (فقط برای نمایش - repo_id را تغییر دهید)
225
+
226
+ # 1. آپلود یک فایل
227
+ # example_single_file_upload()
228
+
229
+ # 2. آپلود یک فولدر
230
+ # example_folder_upload()
231
+
232
+ # 3. آپلود دسته‌ای
233
+ # example_batch_upload()
234
+
235
+ # 4. استفاده پیشرفته
236
+ # example_advanced_config()
237
+
238
+ # 5. بررسی آمار
239
+ example_check_stats()
240
+
241
+ # 6. مدیریت خطاها
242
+ # example_error_handling()
243
+
244
+ print("\n" + "=" * 60)
245
+ print("✅ راهنما کامل شد")
246
+ print("✅ Guide completed")
247
+ print("=" * 60)
248
+
249
+
250
+ if __name__ == "__main__":
251
+ main()
252
+
static/pages/ai-analyst/ai-analyst.css CHANGED
@@ -206,11 +206,13 @@
206
  }
207
 
208
  .decision-card {
209
- background: linear-gradient(135deg, rgba(15, 23, 42, 0.9), rgba(30, 41, 59, 0.7));
 
 
210
  border-radius: var(--radius-lg);
211
  padding: var(--space-6);
212
- border: 1px solid rgba(255, 255, 255, 0.1);
213
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05);
214
  position: relative;
215
  overflow: hidden;
216
  transition: all 0.3s ease;
@@ -233,8 +235,9 @@
233
  }
234
 
235
  .decision-card.bullish {
236
- border-color: rgba(34, 197, 94, 0.3);
237
- background: linear-gradient(135deg, rgba(34, 197, 94, 0.1), rgba(15, 23, 42, 0.8));
 
238
  }
239
 
240
  .decision-card.bullish::before {
@@ -242,8 +245,9 @@
242
  }
243
 
244
  .decision-card.bearish {
245
- border-color: rgba(239, 68, 68, 0.3);
246
- background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(15, 23, 42, 0.8));
 
247
  }
248
 
249
  .decision-card.bearish::before {
@@ -251,8 +255,9 @@
251
  }
252
 
253
  .decision-card.neutral {
254
- border-color: rgba(234, 179, 8, 0.3);
255
- background: linear-gradient(135deg, rgba(234, 179, 8, 0.1), rgba(15, 23, 42, 0.8));
 
256
  }
257
 
258
  .decision-card.neutral::before {
@@ -289,26 +294,42 @@
289
  }
290
 
291
  .current-price {
292
- font-size: var(--font-size-xl);
293
- font-weight: var(--font-weight-semibold);
294
  color: var(--text-strong);
 
 
 
 
 
 
 
295
  }
296
 
297
  .price-change {
298
- font-size: var(--font-size-sm);
299
- font-weight: var(--font-weight-semibold);
300
- padding: var(--space-1) var(--space-2);
301
  border-radius: var(--radius-md);
 
 
 
 
 
302
  }
303
 
304
  .price-change.positive {
305
  color: #22c55e;
306
- background: rgba(34, 197, 94, 0.1);
 
 
307
  }
308
 
309
  .price-change.negative {
310
  color: #ef4444;
311
- background: rgba(239, 68, 68, 0.1);
 
 
312
  }
313
 
314
  .decision-badge {
@@ -516,6 +537,28 @@
516
  display: flex;
517
  align-items: center;
518
  justify-content: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  }
520
 
521
  .signal-item.bullish .signal-icon,
@@ -631,10 +674,13 @@
631
 
632
  /* Key Levels Card */
633
  .key-levels-card {
634
- background: linear-gradient(135deg, rgba(15, 23, 42, 0.6), rgba(30, 41, 59, 0.4));
 
 
635
  border-radius: var(--radius-lg);
636
  padding: var(--space-5);
637
- border: 1px solid rgba(255, 255, 255, 0.1);
 
638
  }
639
 
640
  .section-title {
@@ -658,16 +704,19 @@
658
  align-items: center;
659
  gap: var(--space-3);
660
  padding: var(--space-4);
661
- background: rgba(255, 255, 255, 0.03);
662
  border-radius: var(--radius-md);
663
- border: 1px solid rgba(255, 255, 255, 0.1);
664
  transition: all 0.3s ease;
 
 
665
  }
666
 
667
  .level-card:hover {
668
- background: rgba(255, 255, 255, 0.05);
669
- transform: translateY(-2px);
670
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
 
671
  }
672
 
673
  .level-card.support {
@@ -680,21 +729,55 @@
680
 
681
  .level-icon {
682
  flex-shrink: 0;
683
- width: 48px;
684
- height: 48px;
685
  display: flex;
686
  align-items: center;
687
  justify-content: center;
688
- border-radius: var(--radius-md);
689
- background: rgba(255, 255, 255, 0.05);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
  }
691
 
692
  .level-card.support .level-icon {
693
- background: rgba(239, 68, 68, 0.1);
 
694
  }
695
 
696
  .level-card.resistance .level-icon {
697
- background: rgba(34, 197, 94, 0.1);
 
698
  }
699
 
700
  .level-info {
@@ -712,10 +795,16 @@
712
 
713
  .level-value {
714
  display: block;
715
- font-size: var(--font-size-xl);
716
- font-weight: var(--font-weight-bold);
717
  color: var(--text-strong);
718
  margin-bottom: var(--space-1);
 
 
 
 
 
 
719
  }
720
 
721
  .level-distance {
@@ -726,7 +815,11 @@
726
 
727
  /* Technical Indicators */
728
  .indicators-section {
729
- background: linear-gradient(135deg, rgba(15, 23, 42, 0.6), rgba(30, 41, 59, 0.4));
 
 
 
 
730
  }
731
 
732
  .indicators-grid {
@@ -737,15 +830,19 @@
737
 
738
  .indicator-card {
739
  padding: var(--space-4);
740
- background: rgba(255, 255, 255, 0.03);
741
  border-radius: var(--radius-md);
742
- border: 1px solid rgba(255, 255, 255, 0.1);
743
  transition: all 0.3s ease;
 
 
744
  }
745
 
746
  .indicator-card:hover {
747
- background: rgba(255, 255, 255, 0.05);
748
- transform: translateY(-2px);
 
 
749
  }
750
 
751
  .indicator-header {
@@ -762,9 +859,11 @@
762
  }
763
 
764
  .indicator-value {
765
- font-size: var(--font-size-lg);
766
- font-weight: var(--font-weight-bold);
767
  color: var(--text-strong);
 
 
768
  }
769
 
770
  .indicator-value.overbought {
@@ -804,17 +903,20 @@
804
 
805
  .target.support {
806
  border-left: 4px solid #ef4444;
807
- background: rgba(239, 68, 68, 0.05);
 
808
  }
809
 
810
  .target.resistance {
811
  border-left: 4px solid #22c55e;
812
- background: rgba(34, 197, 94, 0.05);
 
813
  }
814
 
815
  .target.primary {
816
  border-left: 4px solid var(--color-primary);
817
- background: rgba(59, 130, 246, 0.05);
 
818
  }
819
 
820
  /* Signals Grid Improvements */
@@ -825,19 +927,23 @@
825
  }
826
 
827
  .signal-item {
828
- background: rgba(255, 255, 255, 0.03);
829
  padding: var(--space-4);
830
  border-radius: var(--radius-md);
831
  display: flex;
832
  align-items: center;
833
  gap: var(--space-3);
834
- border: 1px solid rgba(255, 255, 255, 0.1);
835
  transition: all 0.3s ease;
 
 
836
  }
837
 
838
  .signal-item:hover {
839
- background: rgba(255, 255, 255, 0.05);
840
- transform: translateX(4px);
 
 
841
  }
842
 
843
  .signal-item.bullish {
@@ -868,16 +974,19 @@
868
  font-size: var(--font-size-sm);
869
  color: var(--text-muted);
870
  font-weight: var(--font-weight-medium);
 
871
  }
872
 
873
  .signal-value {
874
- font-size: var(--font-size-sm);
875
- font-weight: var(--font-weight-bold);
876
  color: var(--text-strong);
877
  text-transform: capitalize;
878
  display: flex;
879
  align-items: center;
880
  gap: var(--space-1);
 
 
881
  }
882
 
883
  .signal-value.bullish {
@@ -900,9 +1009,19 @@
900
  .target {
901
  flex: 1;
902
  text-align: center;
903
- padding: var(--space-3);
904
- background: var(--surface-base);
905
  border-radius: var(--radius-md);
 
 
 
 
 
 
 
 
 
 
906
  }
907
 
908
  .target span {
@@ -910,17 +1029,43 @@
910
  font-size: var(--font-size-xs);
911
  color: var(--text-muted);
912
  text-transform: uppercase;
913
- margin-bottom: var(--space-1);
 
 
914
  }
915
 
916
  .target strong {
917
- font-size: var(--font-size-lg);
 
918
  color: var(--text-strong);
 
 
 
 
 
 
 
 
 
 
 
919
  }
920
 
921
- .target.support strong { color: var(--color-danger); }
922
- .target.resistance strong { color: var(--color-success); }
923
- .target.primary strong { color: var(--color-primary); }
 
 
 
 
 
 
 
 
 
 
 
 
924
 
925
  .disclaimer {
926
  display: flex;
 
206
  }
207
 
208
  .decision-card {
209
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.1));
210
+ backdrop-filter: blur(20px);
211
+ -webkit-backdrop-filter: blur(20px);
212
  border-radius: var(--radius-lg);
213
  padding: var(--space-6);
214
+ border: 1px solid rgba(255, 255, 255, 0.25);
215
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1);
216
  position: relative;
217
  overflow: hidden;
218
  transition: all 0.3s ease;
 
235
  }
236
 
237
  .decision-card.bullish {
238
+ border-color: rgba(34, 197, 94, 0.5);
239
+ background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(255, 255, 255, 0.15));
240
+ box-shadow: 0 8px 32px rgba(34, 197, 94, 0.2), 0 0 0 1px rgba(34, 197, 94, 0.3);
241
  }
242
 
243
  .decision-card.bullish::before {
 
245
  }
246
 
247
  .decision-card.bearish {
248
+ border-color: rgba(239, 68, 68, 0.5);
249
+ background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(255, 255, 255, 0.15));
250
+ box-shadow: 0 8px 32px rgba(239, 68, 68, 0.2), 0 0 0 1px rgba(239, 68, 68, 0.3);
251
  }
252
 
253
  .decision-card.bearish::before {
 
255
  }
256
 
257
  .decision-card.neutral {
258
+ border-color: rgba(234, 179, 8, 0.5);
259
+ background: linear-gradient(135deg, rgba(234, 179, 8, 0.2), rgba(255, 255, 255, 0.15));
260
+ box-shadow: 0 8px 32px rgba(234, 179, 8, 0.2), 0 0 0 1px rgba(234, 179, 8, 0.3);
261
  }
262
 
263
  .decision-card.neutral::before {
 
294
  }
295
 
296
  .current-price {
297
+ font-size: 2rem;
298
+ font-weight: 700;
299
  color: var(--text-strong);
300
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
301
+ letter-spacing: -0.02em;
302
+ background: linear-gradient(135deg, #f8fafc, #cbd5e1);
303
+ -webkit-background-clip: text;
304
+ -webkit-text-fill-color: transparent;
305
+ background-clip: text;
306
+ text-shadow: 0 0 30px rgba(255, 255, 255, 0.1);
307
  }
308
 
309
  .price-change {
310
+ font-size: 0.95rem;
311
+ font-weight: 700;
312
+ padding: var(--space-2) var(--space-3);
313
  border-radius: var(--radius-md);
314
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
315
+ letter-spacing: 0.02em;
316
+ display: inline-flex;
317
+ align-items: center;
318
+ gap: 0.25rem;
319
  }
320
 
321
  .price-change.positive {
322
  color: #22c55e;
323
+ background: rgba(34, 197, 94, 0.2);
324
+ border: 1px solid rgba(34, 197, 94, 0.3);
325
+ box-shadow: 0 0 12px rgba(34, 197, 94, 0.2);
326
  }
327
 
328
  .price-change.negative {
329
  color: #ef4444;
330
+ background: rgba(239, 68, 68, 0.2);
331
+ border: 1px solid rgba(239, 68, 68, 0.3);
332
+ box-shadow: 0 0 12px rgba(239, 68, 68, 0.2);
333
  }
334
 
335
  .decision-badge {
 
537
  display: flex;
538
  align-items: center;
539
  justify-content: center;
540
+ width: 32px;
541
+ height: 32px;
542
+ flex-shrink: 0;
543
+ }
544
+
545
+ .signal-icon svg {
546
+ width: 20px;
547
+ height: 20px;
548
+ stroke-width: 2.5;
549
+ filter: drop-shadow(0 0 4px currentColor);
550
+ animation: iconPulse 2s ease-in-out infinite;
551
+ }
552
+
553
+ @keyframes iconPulse {
554
+ 0%, 100% {
555
+ opacity: 1;
556
+ transform: scale(1);
557
+ }
558
+ 50% {
559
+ opacity: 0.8;
560
+ transform: scale(1.1);
561
+ }
562
  }
563
 
564
  .signal-item.bullish .signal-icon,
 
674
 
675
  /* Key Levels Card */
676
  .key-levels-card {
677
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.08));
678
+ backdrop-filter: blur(15px);
679
+ -webkit-backdrop-filter: blur(15px);
680
  border-radius: var(--radius-lg);
681
  padding: var(--space-5);
682
+ border: 1px solid rgba(255, 255, 255, 0.2);
683
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
684
  }
685
 
686
  .section-title {
 
704
  align-items: center;
705
  gap: var(--space-3);
706
  padding: var(--space-4);
707
+ background: rgba(255, 255, 255, 0.12);
708
  border-radius: var(--radius-md);
709
+ border: 1px solid rgba(255, 255, 255, 0.2);
710
  transition: all 0.3s ease;
711
+ backdrop-filter: blur(10px);
712
+ -webkit-backdrop-filter: blur(10px);
713
  }
714
 
715
  .level-card:hover {
716
+ background: rgba(255, 255, 255, 0.18);
717
+ transform: translateY(-4px) scale(1.02);
718
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
719
+ border-color: rgba(255, 255, 255, 0.3);
720
  }
721
 
722
  .level-card.support {
 
729
 
730
  .level-icon {
731
  flex-shrink: 0;
732
+ width: 56px;
733
+ height: 56px;
734
  display: flex;
735
  align-items: center;
736
  justify-content: center;
737
+ border-radius: var(--radius-lg);
738
+ background: rgba(255, 255, 255, 0.15);
739
+ transition: all 0.3s ease;
740
+ position: relative;
741
+ overflow: hidden;
742
+ }
743
+
744
+ .level-icon::before {
745
+ content: '';
746
+ position: absolute;
747
+ inset: 0;
748
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), transparent);
749
+ opacity: 0;
750
+ transition: opacity 0.3s ease;
751
+ }
752
+
753
+ .level-card:hover .level-icon::before {
754
+ opacity: 1;
755
+ }
756
+
757
+ .level-icon svg {
758
+ position: relative;
759
+ z-index: 1;
760
+ filter: drop-shadow(0 0 8px currentColor);
761
+ animation: iconFloat 3s ease-in-out infinite;
762
+ }
763
+
764
+ @keyframes iconFloat {
765
+ 0%, 100% {
766
+ transform: translateY(0px);
767
+ }
768
+ 50% {
769
+ transform: translateY(-4px);
770
+ }
771
  }
772
 
773
  .level-card.support .level-icon {
774
+ background: rgba(239, 68, 68, 0.2);
775
+ border: 2px solid rgba(239, 68, 68, 0.3);
776
  }
777
 
778
  .level-card.resistance .level-icon {
779
+ background: rgba(34, 197, 94, 0.2);
780
+ border: 2px solid rgba(34, 197, 94, 0.3);
781
  }
782
 
783
  .level-info {
 
795
 
796
  .level-value {
797
  display: block;
798
+ font-size: 1.75rem;
799
+ font-weight: 700;
800
  color: var(--text-strong);
801
  margin-bottom: var(--space-1);
802
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
803
+ letter-spacing: -0.01em;
804
+ background: linear-gradient(135deg, #f8fafc, #e2e8f0);
805
+ -webkit-background-clip: text;
806
+ -webkit-text-fill-color: transparent;
807
+ background-clip: text;
808
  }
809
 
810
  .level-distance {
 
815
 
816
  /* Technical Indicators */
817
  .indicators-section {
818
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.08));
819
+ backdrop-filter: blur(15px);
820
+ -webkit-backdrop-filter: blur(15px);
821
+ border: 1px solid rgba(255, 255, 255, 0.2);
822
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
823
  }
824
 
825
  .indicators-grid {
 
830
 
831
  .indicator-card {
832
  padding: var(--space-4);
833
+ background: rgba(255, 255, 255, 0.12);
834
  border-radius: var(--radius-md);
835
+ border: 1px solid rgba(255, 255, 255, 0.2);
836
  transition: all 0.3s ease;
837
+ backdrop-filter: blur(10px);
838
+ -webkit-backdrop-filter: blur(10px);
839
  }
840
 
841
  .indicator-card:hover {
842
+ background: rgba(255, 255, 255, 0.18);
843
+ transform: translateY(-4px) scale(1.02);
844
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
845
+ border-color: rgba(255, 255, 255, 0.3);
846
  }
847
 
848
  .indicator-header {
 
859
  }
860
 
861
  .indicator-value {
862
+ font-size: 1.5rem;
863
+ font-weight: 700;
864
  color: var(--text-strong);
865
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
866
+ letter-spacing: -0.01em;
867
  }
868
 
869
  .indicator-value.overbought {
 
903
 
904
  .target.support {
905
  border-left: 4px solid #ef4444;
906
+ background: rgba(239, 68, 68, 0.15);
907
+ border-color: rgba(239, 68, 68, 0.3);
908
  }
909
 
910
  .target.resistance {
911
  border-left: 4px solid #22c55e;
912
+ background: rgba(34, 197, 94, 0.15);
913
+ border-color: rgba(34, 197, 94, 0.3);
914
  }
915
 
916
  .target.primary {
917
  border-left: 4px solid var(--color-primary);
918
+ background: rgba(59, 130, 246, 0.15);
919
+ border-color: rgba(59, 130, 246, 0.3);
920
  }
921
 
922
  /* Signals Grid Improvements */
 
927
  }
928
 
929
  .signal-item {
930
+ background: rgba(255, 255, 255, 0.12);
931
  padding: var(--space-4);
932
  border-radius: var(--radius-md);
933
  display: flex;
934
  align-items: center;
935
  gap: var(--space-3);
936
+ border: 1px solid rgba(255, 255, 255, 0.2);
937
  transition: all 0.3s ease;
938
+ backdrop-filter: blur(10px);
939
+ -webkit-backdrop-filter: blur(10px);
940
  }
941
 
942
  .signal-item:hover {
943
+ background: rgba(255, 255, 255, 0.18);
944
+ transform: translateX(4px) translateY(-2px);
945
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
946
+ border-color: rgba(255, 255, 255, 0.3);
947
  }
948
 
949
  .signal-item.bullish {
 
974
  font-size: var(--font-size-sm);
975
  color: var(--text-muted);
976
  font-weight: var(--font-weight-medium);
977
+ min-width: 80px;
978
  }
979
 
980
  .signal-value {
981
+ font-size: var(--font-size-base);
982
+ font-weight: 700;
983
  color: var(--text-strong);
984
  text-transform: capitalize;
985
  display: flex;
986
  align-items: center;
987
  gap: var(--space-1);
988
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
989
+ letter-spacing: 0.01em;
990
  }
991
 
992
  .signal-value.bullish {
 
1009
  .target {
1010
  flex: 1;
1011
  text-align: center;
1012
+ padding: var(--space-4);
1013
+ background: rgba(255, 255, 255, 0.12);
1014
  border-radius: var(--radius-md);
1015
+ border: 1px solid rgba(255, 255, 255, 0.2);
1016
+ backdrop-filter: blur(10px);
1017
+ -webkit-backdrop-filter: blur(10px);
1018
+ transition: all 0.3s ease;
1019
+ }
1020
+
1021
+ .target:hover {
1022
+ background: rgba(255, 255, 255, 0.18);
1023
+ transform: translateY(-2px);
1024
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1025
  }
1026
 
1027
  .target span {
 
1029
  font-size: var(--font-size-xs);
1030
  color: var(--text-muted);
1031
  text-transform: uppercase;
1032
+ margin-bottom: var(--space-2);
1033
+ font-weight: 600;
1034
+ letter-spacing: 0.05em;
1035
  }
1036
 
1037
  .target strong {
1038
+ font-size: 1.5rem;
1039
+ font-weight: 700;
1040
  color: var(--text-strong);
1041
+ font-family: 'Space Grotesk', 'Inter', sans-serif;
1042
+ letter-spacing: -0.01em;
1043
+ display: block;
1044
+ }
1045
+
1046
+ .target.support strong {
1047
+ color: #ef4444;
1048
+ background: linear-gradient(135deg, #ef4444, #dc2626);
1049
+ -webkit-background-clip: text;
1050
+ -webkit-text-fill-color: transparent;
1051
+ background-clip: text;
1052
  }
1053
 
1054
+ .target.resistance strong {
1055
+ color: #22c55e;
1056
+ background: linear-gradient(135deg, #22c55e, #16a34a);
1057
+ -webkit-background-clip: text;
1058
+ -webkit-text-fill-color: transparent;
1059
+ background-clip: text;
1060
+ }
1061
+
1062
+ .target.primary strong {
1063
+ color: var(--color-primary);
1064
+ background: linear-gradient(135deg, #3b82f6, #2563eb);
1065
+ -webkit-background-clip: text;
1066
+ -webkit-text-fill-color: transparent;
1067
+ background-clip: text;
1068
+ }
1069
 
1070
  .disclaimer {
1071
  display: flex;
static/pages/ai-analyst/ai-analyst.js CHANGED
@@ -562,7 +562,12 @@ class AIAnalystPage {
562
  <span class="signal-value">${signals.momentum || (rsi ? (rsi > 50 ? 'Bullish' : 'Bearish') : 'Medium')}</span>
563
  </div>
564
  <div class="signal-item">
565
- <span class="signal-icon">${neutralIcon}</span>
 
 
 
 
 
566
  <span class="signal-label">Volume:</span>
567
  <span class="signal-value">${signals.volume || 'Normal'}</span>
568
  </div>
 
562
  <span class="signal-value">${signals.momentum || (rsi ? (rsi > 50 ? 'Bullish' : 'Bearish') : 'Medium')}</span>
563
  </div>
564
  <div class="signal-item">
565
+ <span class="signal-icon">
566
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
567
+ <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
568
+ <path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path>
569
+ </svg>
570
+ </span>
571
  <span class="signal-label">Volume:</span>
572
  <span class="signal-value">${signals.volume || 'Normal'}</span>
573
  </div>
static/pages/ai-analyst/index.html CHANGED
@@ -118,13 +118,16 @@
118
  <div class="panel-body">
119
  <div class="quick-actions">
120
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('BTC')">
121
- <span class="coin-icon">₿</span> Bitcoin
 
122
  </button>
123
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('ETH')">
124
- <span class="coin-icon">Ξ</span> Ethereum
 
125
  </button>
126
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('SOL')">
127
- <span class="coin-icon">◎</span> Solana
 
128
  </button>
129
  </div>
130
  </div>
 
118
  <div class="panel-body">
119
  <div class="quick-actions">
120
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('BTC')">
121
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M12 2v10l8-4"></path></svg>
122
+ Bitcoin
123
  </button>
124
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('ETH')">
125
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
126
+ Ethereum
127
  </button>
128
  <button class="btn btn-secondary" onclick="window.analystPage.quickAnalyze('SOL')">
129
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle></svg>
130
+ Solana
131
  </button>
132
  </div>
133
  </div>
static/pages/models/models.css CHANGED
@@ -66,14 +66,15 @@
66
  justify-content: space-between;
67
  align-items: center;
68
  padding: var(--space-6);
69
- background: rgba(17, 24, 39, 0.7);
70
  backdrop-filter: blur(20px);
71
  -webkit-backdrop-filter: blur(20px);
72
- border: 1px solid rgba(255, 255, 255, 0.1);
73
  border-radius: var(--radius-xl);
74
  margin-bottom: var(--space-6);
75
  position: relative;
76
  overflow: hidden;
 
77
  }
78
 
79
  .page-header.glass-panel::before {
@@ -183,8 +184,9 @@
183
  font-size: var(--font-size-xs);
184
  color: var(--text-muted);
185
  padding: var(--space-2) var(--space-3);
186
- background: rgba(255, 255, 255, 0.05);
187
  border-radius: var(--radius-sm);
 
188
  }
189
 
190
  /* =========================================================================
@@ -203,18 +205,20 @@
203
  align-items: flex-start;
204
  gap: var(--space-4);
205
  padding: var(--space-5);
206
- background: rgba(17, 24, 39, 0.6);
207
  backdrop-filter: blur(15px);
208
  -webkit-backdrop-filter: blur(15px);
209
- border: 1px solid rgba(255, 255, 255, 0.08);
210
  border-radius: var(--radius-xl);
211
  transition: all 0.3s ease;
 
212
  }
213
 
214
  .stat-card.glass-card:hover {
215
  transform: translateY(-4px);
216
- border-color: rgba(255, 255, 255, 0.15);
217
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
 
218
  }
219
 
220
  .stat-icon {
@@ -299,12 +303,13 @@
299
  ========================================================================= */
300
 
301
  .tabs-container.glass-panel {
302
- background: rgba(17, 24, 39, 0.6);
303
  backdrop-filter: blur(15px);
304
- border: 1px solid rgba(255, 255, 255, 0.08);
305
  border-radius: var(--radius-xl);
306
  padding: var(--space-2);
307
  margin-bottom: var(--space-6);
 
308
  }
309
 
310
  .tabs {
@@ -379,8 +384,8 @@
379
  .select-modern {
380
  padding: var(--space-2) var(--space-4);
381
  padding-right: var(--space-8);
382
- background: rgba(17, 24, 39, 0.8);
383
- border: 1px solid rgba(255, 255, 255, 0.1);
384
  border-radius: var(--radius-md);
385
  color: var(--text-secondary);
386
  font-size: var(--font-size-sm);
@@ -419,13 +424,14 @@
419
  }
420
 
421
  .model-card {
422
- background: rgba(17, 24, 39, 0.7);
423
  backdrop-filter: blur(15px);
424
- border: 1px solid rgba(255, 255, 255, 0.08);
425
  border-radius: var(--radius-xl);
426
  overflow: hidden;
427
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
428
  position: relative;
 
429
  }
430
 
431
  .model-card::before {
@@ -443,8 +449,9 @@
443
 
444
  .model-card:hover {
445
  transform: translateY(-6px);
446
- border-color: rgba(139, 92, 246, 0.3);
447
- box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
 
448
  }
449
 
450
  .model-card:hover::before {
@@ -466,8 +473,8 @@
466
  align-items: center;
467
  gap: var(--space-4);
468
  padding: var(--space-5);
469
- background: rgba(0, 0, 0, 0.2);
470
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
471
  }
472
 
473
  .model-icon {
@@ -547,11 +554,12 @@
547
  font-family: 'JetBrains Mono', monospace;
548
  font-size: var(--font-size-xs);
549
  color: var(--text-muted);
550
- background: rgba(0, 0, 0, 0.3);
551
  padding: var(--space-2) var(--space-3);
552
  border-radius: var(--radius-sm);
553
  margin-bottom: var(--space-4);
554
  word-break: break-all;
 
555
  }
556
 
557
  .model-meta {
@@ -565,10 +573,11 @@
565
  align-items: center;
566
  gap: var(--space-1);
567
  padding: var(--space-1) var(--space-3);
568
- background: rgba(255, 255, 255, 0.05);
569
  border-radius: var(--radius-sm);
570
  font-size: var(--font-size-xs);
571
  color: var(--text-muted);
 
572
  }
573
 
574
  .meta-badge svg {
@@ -578,8 +587,8 @@
578
 
579
  .model-footer {
580
  padding: var(--space-4) var(--space-5);
581
- background: rgba(0, 0, 0, 0.15);
582
- border-top: 1px solid rgba(255, 255, 255, 0.05);
583
  display: flex;
584
  gap: var(--space-2);
585
  }
@@ -591,8 +600,8 @@
591
  justify-content: center;
592
  gap: var(--space-2);
593
  padding: var(--space-2) var(--space-3);
594
- background: rgba(255, 255, 255, 0.05);
595
- border: 1px solid rgba(255, 255, 255, 0.1);
596
  border-radius: var(--radius-md);
597
  color: var(--text-secondary);
598
  font-size: var(--font-size-xs);
@@ -624,11 +633,12 @@
624
  .test-panel.glass-panel,
625
  .health-panel.glass-panel,
626
  .catalog-panel.glass-panel {
627
- background: rgba(17, 24, 39, 0.7);
628
  backdrop-filter: blur(15px);
629
- border: 1px solid rgba(255, 255, 255, 0.08);
630
  border-radius: var(--radius-xl);
631
  padding: var(--space-6);
 
632
  }
633
 
634
  .test-header,
@@ -682,8 +692,8 @@
682
  .textarea-modern {
683
  width: 100%;
684
  padding: var(--space-4);
685
- background: rgba(0, 0, 0, 0.3);
686
- border: 1px solid rgba(255, 255, 255, 0.1);
687
  border-radius: var(--radius-md);
688
  color: var(--text-strong);
689
  font-family: inherit;
@@ -706,8 +716,9 @@
706
 
707
  .example-texts {
708
  padding: var(--space-4);
709
- background: rgba(0, 0, 0, 0.2);
710
  border-radius: var(--radius-lg);
 
711
  }
712
 
713
  .example-label {
@@ -724,8 +735,8 @@
724
 
725
  .example-btn {
726
  padding: var(--space-2) var(--space-4);
727
- background: rgba(255, 255, 255, 0.05);
728
- border: 1px solid rgba(255, 255, 255, 0.1);
729
  border-radius: var(--radius-md);
730
  color: var(--text-secondary);
731
  font-size: var(--font-size-sm);
@@ -743,10 +754,11 @@
743
  .test-result {
744
  margin-top: var(--space-6);
745
  padding: var(--space-6);
746
- background: rgba(0, 0, 0, 0.3);
747
- border: 1px solid rgba(255, 255, 255, 0.1);
748
  border-radius: var(--radius-xl);
749
  animation: fadeIn 0.4s ease;
 
750
  }
751
 
752
  .test-result.hidden {
@@ -803,11 +815,12 @@
803
  }
804
 
805
  .result-details {
806
- background: rgba(0, 0, 0, 0.4);
807
  border-radius: var(--radius-md);
808
  padding: var(--space-4);
809
  overflow: auto;
810
  max-height: 300px;
 
811
  }
812
 
813
  .result-json {
@@ -829,11 +842,12 @@
829
  }
830
 
831
  .health-card {
832
- background: rgba(0, 0, 0, 0.3);
833
- border: 1px solid rgba(255, 255, 255, 0.08);
834
  border-radius: var(--radius-lg);
835
  padding: var(--space-4);
836
  transition: all 0.3s ease;
 
837
  }
838
 
839
  .health-card:hover {
@@ -907,8 +921,9 @@
907
  .health-stat {
908
  text-align: center;
909
  padding: var(--space-2);
910
- background: rgba(255, 255, 255, 0.03);
911
  border-radius: var(--radius-sm);
 
912
  }
913
 
914
  .health-stat-value {
@@ -940,8 +955,8 @@
940
  .health-actions .btn {
941
  flex: 1;
942
  padding: var(--space-2);
943
- background: rgba(255, 255, 255, 0.05);
944
- border: 1px solid rgba(255, 255, 255, 0.1);
945
  border-radius: var(--radius-sm);
946
  color: var(--text-secondary);
947
  font-size: var(--font-size-xs);
@@ -966,10 +981,11 @@
966
  }
967
 
968
  .catalog-category {
969
- background: rgba(0, 0, 0, 0.25);
970
- border: 1px solid rgba(255, 255, 255, 0.08);
971
  border-radius: var(--radius-xl);
972
  overflow: hidden;
 
973
  }
974
 
975
  .category-header {
@@ -1025,10 +1041,11 @@
1025
  align-items: center;
1026
  justify-content: space-between;
1027
  padding: var(--space-3);
1028
- background: rgba(255, 255, 255, 0.03);
1029
  border-radius: var(--radius-md);
1030
  margin-bottom: var(--space-2);
1031
  transition: all 0.3s ease;
 
1032
  }
1033
 
1034
  .catalog-model:last-child {
@@ -1036,7 +1053,9 @@
1036
  }
1037
 
1038
  .catalog-model:hover {
1039
- background: rgba(255, 255, 255, 0.08);
 
 
1040
  }
1041
 
1042
  .catalog-model-name {
 
66
  justify-content: space-between;
67
  align-items: center;
68
  padding: var(--space-6);
69
+ background: rgba(255, 255, 255, 0.15);
70
  backdrop-filter: blur(20px);
71
  -webkit-backdrop-filter: blur(20px);
72
+ border: 1px solid rgba(255, 255, 255, 0.25);
73
  border-radius: var(--radius-xl);
74
  margin-bottom: var(--space-6);
75
  position: relative;
76
  overflow: hidden;
77
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
78
  }
79
 
80
  .page-header.glass-panel::before {
 
184
  font-size: var(--font-size-xs);
185
  color: var(--text-muted);
186
  padding: var(--space-2) var(--space-3);
187
+ background: rgba(255, 255, 255, 0.15);
188
  border-radius: var(--radius-sm);
189
+ border: 1px solid rgba(255, 255, 255, 0.2);
190
  }
191
 
192
  /* =========================================================================
 
205
  align-items: flex-start;
206
  gap: var(--space-4);
207
  padding: var(--space-5);
208
+ background: rgba(255, 255, 255, 0.12);
209
  backdrop-filter: blur(15px);
210
  -webkit-backdrop-filter: blur(15px);
211
+ border: 1px solid rgba(255, 255, 255, 0.2);
212
  border-radius: var(--radius-xl);
213
  transition: all 0.3s ease;
214
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
215
  }
216
 
217
  .stat-card.glass-card:hover {
218
  transform: translateY(-4px);
219
+ border-color: rgba(255, 255, 255, 0.35);
220
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
221
+ background: rgba(255, 255, 255, 0.18);
222
  }
223
 
224
  .stat-icon {
 
303
  ========================================================================= */
304
 
305
  .tabs-container.glass-panel {
306
+ background: rgba(255, 255, 255, 0.12);
307
  backdrop-filter: blur(15px);
308
+ border: 1px solid rgba(255, 255, 255, 0.2);
309
  border-radius: var(--radius-xl);
310
  padding: var(--space-2);
311
  margin-bottom: var(--space-6);
312
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
313
  }
314
 
315
  .tabs {
 
384
  .select-modern {
385
  padding: var(--space-2) var(--space-4);
386
  padding-right: var(--space-8);
387
+ background: rgba(255, 255, 255, 0.15);
388
+ border: 1px solid rgba(255, 255, 255, 0.25);
389
  border-radius: var(--radius-md);
390
  color: var(--text-secondary);
391
  font-size: var(--font-size-sm);
 
424
  }
425
 
426
  .model-card {
427
+ background: rgba(255, 255, 255, 0.15);
428
  backdrop-filter: blur(15px);
429
+ border: 1px solid rgba(255, 255, 255, 0.25);
430
  border-radius: var(--radius-xl);
431
  overflow: hidden;
432
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
433
  position: relative;
434
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
435
  }
436
 
437
  .model-card::before {
 
449
 
450
  .model-card:hover {
451
  transform: translateY(-6px);
452
+ border-color: rgba(139, 92, 246, 0.5);
453
+ box-shadow: 0 20px 50px rgba(139, 92, 246, 0.2);
454
+ background: rgba(255, 255, 255, 0.2);
455
  }
456
 
457
  .model-card:hover::before {
 
473
  align-items: center;
474
  gap: var(--space-4);
475
  padding: var(--space-5);
476
+ background: rgba(255, 255, 255, 0.08);
477
+ border-bottom: 1px solid rgba(255, 255, 255, 0.15);
478
  }
479
 
480
  .model-icon {
 
554
  font-family: 'JetBrains Mono', monospace;
555
  font-size: var(--font-size-xs);
556
  color: var(--text-muted);
557
+ background: rgba(255, 255, 255, 0.1);
558
  padding: var(--space-2) var(--space-3);
559
  border-radius: var(--radius-sm);
560
  margin-bottom: var(--space-4);
561
  word-break: break-all;
562
+ border: 1px solid rgba(255, 255, 255, 0.15);
563
  }
564
 
565
  .model-meta {
 
573
  align-items: center;
574
  gap: var(--space-1);
575
  padding: var(--space-1) var(--space-3);
576
+ background: rgba(255, 255, 255, 0.15);
577
  border-radius: var(--radius-sm);
578
  font-size: var(--font-size-xs);
579
  color: var(--text-muted);
580
+ border: 1px solid rgba(255, 255, 255, 0.2);
581
  }
582
 
583
  .meta-badge svg {
 
587
 
588
  .model-footer {
589
  padding: var(--space-4) var(--space-5);
590
+ background: rgba(255, 255, 255, 0.08);
591
+ border-top: 1px solid rgba(255, 255, 255, 0.15);
592
  display: flex;
593
  gap: var(--space-2);
594
  }
 
600
  justify-content: center;
601
  gap: var(--space-2);
602
  padding: var(--space-2) var(--space-3);
603
+ background: rgba(255, 255, 255, 0.15);
604
+ border: 1px solid rgba(255, 255, 255, 0.25);
605
  border-radius: var(--radius-md);
606
  color: var(--text-secondary);
607
  font-size: var(--font-size-xs);
 
633
  .test-panel.glass-panel,
634
  .health-panel.glass-panel,
635
  .catalog-panel.glass-panel {
636
+ background: rgba(255, 255, 255, 0.15);
637
  backdrop-filter: blur(15px);
638
+ border: 1px solid rgba(255, 255, 255, 0.25);
639
  border-radius: var(--radius-xl);
640
  padding: var(--space-6);
641
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
642
  }
643
 
644
  .test-header,
 
692
  .textarea-modern {
693
  width: 100%;
694
  padding: var(--space-4);
695
+ background: rgba(255, 255, 255, 0.12);
696
+ border: 1px solid rgba(255, 255, 255, 0.25);
697
  border-radius: var(--radius-md);
698
  color: var(--text-strong);
699
  font-family: inherit;
 
716
 
717
  .example-texts {
718
  padding: var(--space-4);
719
+ background: rgba(255, 255, 255, 0.08);
720
  border-radius: var(--radius-lg);
721
+ border: 1px solid rgba(255, 255, 255, 0.15);
722
  }
723
 
724
  .example-label {
 
735
 
736
  .example-btn {
737
  padding: var(--space-2) var(--space-4);
738
+ background: rgba(255, 255, 255, 0.15);
739
+ border: 1px solid rgba(255, 255, 255, 0.25);
740
  border-radius: var(--radius-md);
741
  color: var(--text-secondary);
742
  font-size: var(--font-size-sm);
 
754
  .test-result {
755
  margin-top: var(--space-6);
756
  padding: var(--space-6);
757
+ background: rgba(255, 255, 255, 0.12);
758
+ border: 1px solid rgba(255, 255, 255, 0.25);
759
  border-radius: var(--radius-xl);
760
  animation: fadeIn 0.4s ease;
761
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
762
  }
763
 
764
  .test-result.hidden {
 
815
  }
816
 
817
  .result-details {
818
+ background: rgba(255, 255, 255, 0.1);
819
  border-radius: var(--radius-md);
820
  padding: var(--space-4);
821
  overflow: auto;
822
  max-height: 300px;
823
+ border: 1px solid rgba(255, 255, 255, 0.15);
824
  }
825
 
826
  .result-json {
 
842
  }
843
 
844
  .health-card {
845
+ background: rgba(255, 255, 255, 0.12);
846
+ border: 1px solid rgba(255, 255, 255, 0.2);
847
  border-radius: var(--radius-lg);
848
  padding: var(--space-4);
849
  transition: all 0.3s ease;
850
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
851
  }
852
 
853
  .health-card:hover {
 
921
  .health-stat {
922
  text-align: center;
923
  padding: var(--space-2);
924
+ background: rgba(255, 255, 255, 0.12);
925
  border-radius: var(--radius-sm);
926
+ border: 1px solid rgba(255, 255, 255, 0.15);
927
  }
928
 
929
  .health-stat-value {
 
955
  .health-actions .btn {
956
  flex: 1;
957
  padding: var(--space-2);
958
+ background: rgba(255, 255, 255, 0.15);
959
+ border: 1px solid rgba(255, 255, 255, 0.25);
960
  border-radius: var(--radius-sm);
961
  color: var(--text-secondary);
962
  font-size: var(--font-size-xs);
 
981
  }
982
 
983
  .catalog-category {
984
+ background: rgba(255, 255, 255, 0.12);
985
+ border: 1px solid rgba(255, 255, 255, 0.2);
986
  border-radius: var(--radius-xl);
987
  overflow: hidden;
988
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
989
  }
990
 
991
  .category-header {
 
1041
  align-items: center;
1042
  justify-content: space-between;
1043
  padding: var(--space-3);
1044
+ background: rgba(255, 255, 255, 0.12);
1045
  border-radius: var(--radius-md);
1046
  margin-bottom: var(--space-2);
1047
  transition: all 0.3s ease;
1048
+ border: 1px solid rgba(255, 255, 255, 0.15);
1049
  }
1050
 
1051
  .catalog-model:last-child {
 
1053
  }
1054
 
1055
  .catalog-model:hover {
1056
+ background: rgba(255, 255, 255, 0.2);
1057
+ border-color: rgba(255, 255, 255, 0.3);
1058
+ transform: translateX(4px);
1059
  }
1060
 
1061
  .catalog-model-name {
static/pages/technical-analysis/visual-strategy-builder.html CHANGED
@@ -761,45 +761,45 @@
761
 
762
  <!-- Page Header -->
763
  <div class="header" style="background: var(--glass-bg); backdrop-filter: blur(20px); border-bottom: 1px solid var(--glass-border); padding: 1rem 1.5rem; display: flex; align-items: center; justify-content: space-between;">
764
- <div class="header-title">
765
- <span>🎯</span>
766
- <span>HTS - آزمایشگاه بصری استراتژی ترید</span>
767
- </div>
768
 
769
- <div class="header-actions">
770
- <button class="btn btn-success" id="executeBtn">
771
- <span>▶️</span>
772
- <span>اجرا</span>
773
- </button>
774
-
775
- <button class="btn" id="pauseBtn" disabled>
776
- <span>⏸️</span>
777
- <span>توقف</span>
778
- </button>
779
-
780
- <button class="btn" id="resetBtn">
781
- <span>🔄</span>
782
- <span>ریست</span>
783
- </button>
784
-
785
- <button class="btn btn-primary" id="saveBtn">
786
- <span>💾</span>
787
- <span>ذخیره</span>
788
- </button>
789
-
790
- <button class="btn" id="loadBtn">
791
- <span>📁</span>
792
- <span>بارگذاری</span>
793
- </button>
794
-
795
- <button class="btn" id="exportBtn">
796
- <span>📤</span>
797
- <span>خروجی</span>
798
- </button>
799
- </div>
800
  </div>
801
 
802
- <!-- Main Content -->
803
  <div class="main-content" style="flex: 1; overflow: auto;">
804
  <!-- Component Library -->
805
  <aside class="component-library">
@@ -1102,7 +1102,7 @@
1102
  <div class="result-metric-value danger" id="liveDrawdown">-۰٪</div>
1103
  </div>
1104
  </div>
1105
- </div>
1106
  </div>
1107
  </div>
1108
  </main>
 
761
 
762
  <!-- Page Header -->
763
  <div class="header" style="background: var(--glass-bg); backdrop-filter: blur(20px); border-bottom: 1px solid var(--glass-border); padding: 1rem 1.5rem; display: flex; align-items: center; justify-content: space-between;">
764
+ <div class="header-title">
765
+ <span>🎯</span>
766
+ <span>HTS - آزمایشگاه بصری استراتژی ترید</span>
767
+ </div>
768
 
769
+ <div class="header-actions">
770
+ <button class="btn btn-success" id="executeBtn">
771
+ <span>▶️</span>
772
+ <span>اجرا</span>
773
+ </button>
774
+
775
+ <button class="btn" id="pauseBtn" disabled>
776
+ <span>⏸️</span>
777
+ <span>توقف</span>
778
+ </button>
779
+
780
+ <button class="btn" id="resetBtn">
781
+ <span>🔄</span>
782
+ <span>ریست</span>
783
+ </button>
784
+
785
+ <button class="btn btn-primary" id="saveBtn">
786
+ <span>💾</span>
787
+ <span>ذخیره</span>
788
+ </button>
789
+
790
+ <button class="btn" id="loadBtn">
791
+ <span>📁</span>
792
+ <span>بارگذاری</span>
793
+ </button>
794
+
795
+ <button class="btn" id="exportBtn">
796
+ <span>📤</span>
797
+ <span>خروجی</span>
798
+ </button>
799
+ </div>
800
  </div>
801
 
802
+ <!-- Main Content -->
803
  <div class="main-content" style="flex: 1; overflow: auto;">
804
  <!-- Component Library -->
805
  <aside class="component-library">
 
1102
  <div class="result-metric-value danger" id="liveDrawdown">-۰٪</div>
1103
  </div>
1104
  </div>
1105
+ </div>
1106
  </div>
1107
  </div>
1108
  </main>
static/splash.html CHANGED
@@ -4,6 +4,7 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Crypto Intelligence Hub | Welcome</title>
 
7
  <style>
8
  * {
9
  margin: 0;
@@ -17,6 +18,7 @@
17
  --accent-cyan: #2dd4bf;
18
  --accent-purple: #818cf8;
19
  --accent-pink: #ec4899;
 
20
  --text-primary: #f8fafc;
21
  --text-secondary: rgba(241, 245, 249, 0.75);
22
  }
@@ -24,7 +26,7 @@
24
  body {
25
  min-height: 100vh;
26
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
27
- background: linear-gradient(135deg, var(--bg-primary), #020617, var(--bg-secondary));
28
  color: var(--text-primary);
29
  display: flex;
30
  align-items: center;
@@ -33,41 +35,80 @@
33
  position: relative;
34
  }
35
 
36
- /* Animated background particles */
37
- .particles {
38
  position: absolute;
39
- top: 0;
40
- left: 0;
41
- width: 100%;
42
- height: 100%;
43
  overflow: hidden;
44
  z-index: 0;
45
  }
46
 
47
- .particle {
48
  position: absolute;
49
- width: 2px;
50
- height: 2px;
51
- background: var(--accent-cyan);
52
  border-radius: 50%;
53
- opacity: 0.3;
54
- animation: float-particle 10s infinite ease-in-out;
 
55
  }
56
 
57
- @keyframes float-particle {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  0%, 100% {
59
- transform: translateY(0) translateX(0);
60
- opacity: 0;
61
  }
62
- 10% {
63
- opacity: 0.3;
64
  }
65
- 90% {
66
- opacity: 0.3;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
  100% {
69
- transform: translateY(-100vh) translateX(100px);
70
- opacity: 0;
71
  }
72
  }
73
 
@@ -75,67 +116,163 @@
75
  position: relative;
76
  z-index: 1;
77
  text-align: center;
78
- max-width: 800px;
79
  padding: 2rem;
 
 
 
 
 
 
 
 
 
 
80
  }
81
 
82
  .logo-container {
83
  margin-bottom: 3rem;
84
- animation: fadeInDown 1s ease-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
  .logo {
88
- width: 120px;
89
- height: 120px;
90
- margin: 0 auto 2rem;
91
- background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple));
92
- border-radius: 30px;
93
  display: flex;
94
  align-items: center;
95
  justify-content: center;
96
  box-shadow:
97
- 0 20px 60px rgba(45, 212, 191, 0.3),
98
- 0 0 100px rgba(129, 140, 248, 0.2);
99
- animation: float 3s ease-in-out infinite, pulse 2s ease-in-out infinite;
 
100
  position: relative;
 
101
  }
102
 
103
  .logo::before {
104
  content: '';
105
  position: absolute;
106
  inset: -4px;
107
- background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple));
108
- border-radius: 32px;
109
- opacity: 0.3;
110
- filter: blur(20px);
111
- animation: pulse 2s ease-in-out infinite;
 
112
  }
113
 
114
- .logo svg {
115
- position: relative;
116
- z-index: 1;
 
 
 
117
  }
118
 
119
- @keyframes float {
120
  0%, 100% {
121
- transform: translateY(0px);
 
 
 
122
  }
123
  50% {
124
- transform: translateY(-20px);
 
 
 
125
  }
126
  }
127
 
128
- @keyframes pulse {
129
  0%, 100% {
130
- opacity: 0.3;
131
  transform: scale(1);
132
  }
133
  50% {
134
- opacity: 0.5;
135
  transform: scale(1.05);
136
  }
137
  }
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  @keyframes fadeInDown {
140
  from {
141
  opacity: 0;
@@ -147,6 +284,14 @@
147
  }
148
  }
149
 
 
 
 
 
 
 
 
 
150
  @keyframes fadeInUp {
151
  from {
152
  opacity: 0;
@@ -158,95 +303,151 @@
158
  }
159
  }
160
 
161
- h1 {
162
- font-family: 'Space Grotesk', -apple-system, sans-serif;
163
- font-size: 3.5rem;
164
- font-weight: 700;
165
- margin-bottom: 1.5rem;
166
- background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple), var(--accent-pink));
167
- -webkit-background-clip: text;
168
- background-clip: text;
169
- -webkit-text-fill-color: transparent;
170
- animation: fadeInDown 1s ease-out 0.2s both;
171
- }
172
-
173
- .subtitle {
174
- color: var(--text-secondary);
175
- font-size: 1.3rem;
176
- margin-bottom: 3rem;
177
- line-height: 1.6;
178
- animation: fadeInUp 1s ease-out 0.4s both;
179
- }
180
-
181
  .features {
182
  display: grid;
183
- grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
184
- gap: 1.5rem;
185
- margin-bottom: 3rem;
186
- animation: fadeInUp 1s ease-out 0.6s both;
187
  }
188
 
189
  .feature {
190
- padding: 1.5rem;
191
- background: rgba(255, 255, 255, 0.03);
192
- border: 1px solid rgba(255, 255, 255, 0.08);
193
- border-radius: 16px;
194
- backdrop-filter: blur(10px);
195
- transition: all 0.3s ease;
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
 
198
  .feature:hover {
199
- background: rgba(255, 255, 255, 0.05);
200
  border-color: var(--accent-cyan);
201
- transform: translateY(-5px);
 
 
 
 
 
202
  }
203
 
204
  .feature-icon {
205
- font-size: 2.5rem;
206
- margin-bottom: 1rem;
207
- filter: drop-shadow(0 0 10px rgba(45, 212, 191, 0.5));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  }
209
 
210
  .feature-text {
211
  color: var(--text-primary);
212
- font-weight: 500;
213
- font-size: 0.95rem;
 
 
214
  }
215
 
216
  .loading-section {
217
  margin-top: 3rem;
218
- animation: fadeInUp 1s ease-out 0.8s both;
 
 
 
 
 
 
219
  }
220
 
221
  .progress-bar {
222
  width: 100%;
223
- max-width: 400px;
224
- height: 6px;
225
  background: rgba(255, 255, 255, 0.1);
226
  border-radius: 999px;
227
  overflow: hidden;
228
- margin: 2rem auto;
229
  position: relative;
 
230
  }
231
 
232
  .progress-fill {
233
  height: 100%;
234
  width: 0;
235
- background: linear-gradient(90deg, var(--accent-cyan), var(--accent-purple), var(--accent-pink));
 
236
  border-radius: 999px;
237
- animation: progress 3s ease-in-out forwards;
238
  position: relative;
 
239
  }
240
 
241
  .progress-fill::after {
242
  content: '';
243
  position: absolute;
244
  top: 0;
 
245
  right: 0;
246
- width: 100px;
247
- height: 100%;
248
- background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3));
249
- animation: shimmer 1s infinite;
250
  }
251
 
252
  @keyframes progress {
@@ -255,35 +456,84 @@
255
  }
256
  }
257
 
 
 
 
 
 
 
 
 
 
258
  @keyframes shimmer {
259
- to {
 
 
 
260
  transform: translateX(100%);
261
  }
262
  }
263
 
264
  .loading-text {
265
  color: var(--text-secondary);
266
- font-size: 1rem;
267
- margin-top: 1rem;
268
- animation: pulse-text 2s ease-in-out infinite;
 
 
269
  }
270
 
271
- @keyframes pulse-text {
272
  0%, 100% {
273
- opacity: 0.6;
274
  }
275
  50% {
276
  opacity: 1;
277
  }
278
  }
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  .version {
281
  position: absolute;
282
  bottom: 2rem;
283
  right: 2rem;
284
  color: var(--text-secondary);
285
- font-size: 0.85rem;
286
- opacity: 0.5;
 
287
  }
288
 
289
  @media (max-width: 768px) {
@@ -301,32 +551,56 @@
301
  }
302
 
303
  .feature {
304
- padding: 1rem;
305
  }
306
 
307
- .feature-icon {
308
- font-size: 2rem;
 
309
  }
310
 
311
- .logo {
312
- width: 100px;
313
- height: 100px;
314
  }
315
  }
316
  </style>
317
  </head>
318
  <body>
319
- <!-- Animated particles background -->
320
- <div class="particles" id="particles"></div>
 
 
 
 
 
 
 
321
 
322
  <div class="container">
323
  <div class="logo-container">
324
- <div class="logo">
325
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
326
- <path d="M12 2L2 7L12 12L22 7L12 2Z"></path>
327
- <path d="M2 17L12 22L22 17"></path>
328
- <path d="M2 12L12 17L22 12"></path>
329
- </svg>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  </div>
331
  </div>
332
 
@@ -337,33 +611,57 @@
337
 
338
  <div class="features">
339
  <div class="feature">
340
- <div class="feature-icon">📊</div>
 
 
 
 
 
 
341
  <div class="feature-text">Real-time Market Data</div>
342
  </div>
343
  <div class="feature">
344
- <div class="feature-icon">🤖</div>
 
 
 
 
 
 
 
345
  <div class="feature-text">AI-Powered Analysis</div>
346
  </div>
347
  <div class="feature">
348
- <div class="feature-icon">📈</div>
 
 
 
 
349
  <div class="feature-text">Technical Indicators</div>
350
  </div>
351
  <div class="feature">
352
- <div class="feature-icon">🔔</div>
 
 
 
 
 
353
  <div class="feature-text">Smart Alerts</div>
354
  </div>
355
  </div>
356
 
357
  <div class="loading-section">
358
- <div class="progress-bar">
359
- <div class="progress-fill"></div>
 
 
360
  </div>
361
  <div class="loading-text" id="loadingText">
362
  Initializing platform...
363
  </div>
364
  <a href="/static/pages/dashboard/index.html"
365
  onclick="sessionStorage.setItem('skipSplash', 'true');"
366
- style="display: inline-block; margin-top: 1rem; color: var(--accent-cyan); text-decoration: none; font-weight: 500; transition: color 0.3s;">
367
  Skip to Dashboard →
368
  </a>
369
  </div>
@@ -372,20 +670,7 @@
372
  <div class="version">v1.0.0</div>
373
 
374
  <script>
375
- // Create animated particles
376
- const particlesContainer = document.getElementById('particles');
377
- const particleCount = 30;
378
-
379
- for (let i = 0; i < particleCount; i++) {
380
- const particle = document.createElement('div');
381
- particle.className = 'particle';
382
- particle.style.left = Math.random() * 100 + '%';
383
- particle.style.animationDelay = Math.random() * 10 + 's';
384
- particle.style.animationDuration = (8 + Math.random() * 4) + 's';
385
- particlesContainer.appendChild(particle);
386
- }
387
-
388
- // Loading messages
389
  const loadingMessages = [
390
  'Initializing platform...',
391
  'Loading market data...',
@@ -398,25 +683,32 @@
398
  const loadingText = document.getElementById('loadingText');
399
 
400
  const messageInterval = setInterval(() => {
401
- currentMessage++;
402
- if (currentMessage < loadingMessages.length) {
403
- loadingText.textContent = loadingMessages[currentMessage];
 
 
 
 
404
  }
405
- }, 600);
406
 
407
- // Redirect to dashboard after animation (reduced time for faster loading)
408
  setTimeout(() => {
409
  clearInterval(messageInterval);
410
- loadingText.textContent = 'Welcome! 🚀';
 
 
 
 
411
 
412
  // Save preference to skip splash next time
413
  sessionStorage.setItem('skipSplash', 'true');
414
 
415
  setTimeout(() => {
416
  window.location.href = '/static/pages/dashboard/index.html';
417
- }, 300);
418
- }, 1500); // Reduced from 3000ms to 1500ms for faster loading
419
  </script>
420
  </body>
421
  </html>
422
-
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Crypto Intelligence Hub | Welcome</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Space+Grotesk:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
  <style>
9
  * {
10
  margin: 0;
 
18
  --accent-cyan: #2dd4bf;
19
  --accent-purple: #818cf8;
20
  --accent-pink: #ec4899;
21
+ --accent-blue: #3b82f6;
22
  --text-primary: #f8fafc;
23
  --text-secondary: rgba(241, 245, 249, 0.75);
24
  }
 
26
  body {
27
  min-height: 100vh;
28
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
29
+ background: linear-gradient(135deg, var(--bg-primary) 0%, #020617 50%, var(--bg-secondary) 100%);
30
  color: var(--text-primary);
31
  display: flex;
32
  align-items: center;
 
35
  position: relative;
36
  }
37
 
38
+ /* Animated gradient orbs */
39
+ .gradient-orbs {
40
  position: absolute;
41
+ inset: 0;
 
 
 
42
  overflow: hidden;
43
  z-index: 0;
44
  }
45
 
46
+ .orb {
47
  position: absolute;
 
 
 
48
  border-radius: 50%;
49
+ filter: blur(80px);
50
+ opacity: 0.4;
51
+ animation: float-orb 20s ease-in-out infinite;
52
  }
53
 
54
+ .orb-1 {
55
+ width: 600px;
56
+ height: 600px;
57
+ background: radial-gradient(circle, var(--accent-cyan) 0%, transparent 70%);
58
+ top: -300px;
59
+ left: -200px;
60
+ animation-delay: 0s;
61
+ }
62
+
63
+ .orb-2 {
64
+ width: 500px;
65
+ height: 500px;
66
+ background: radial-gradient(circle, var(--accent-purple) 0%, transparent 70%);
67
+ bottom: -250px;
68
+ right: -150px;
69
+ animation-delay: 5s;
70
+ }
71
+
72
+ .orb-3 {
73
+ width: 400px;
74
+ height: 400px;
75
+ background: radial-gradient(circle, var(--accent-pink) 0%, transparent 70%);
76
+ top: 50%;
77
+ left: 50%;
78
+ transform: translate(-50%, -50%);
79
+ animation-delay: 10s;
80
+ }
81
+
82
+ @keyframes float-orb {
83
  0%, 100% {
84
+ transform: translate(0, 0) scale(1);
 
85
  }
86
+ 33% {
87
+ transform: translate(40px, -40px) scale(1.1);
88
  }
89
+ 66% {
90
+ transform: translate(-30px, 30px) scale(0.9);
91
+ }
92
+ }
93
+
94
+ /* Animated grid background */
95
+ .grid-background {
96
+ position: absolute;
97
+ inset: 0;
98
+ background-image:
99
+ linear-gradient(rgba(45, 212, 191, 0.03) 1px, transparent 1px),
100
+ linear-gradient(90deg, rgba(45, 212, 191, 0.03) 1px, transparent 1px);
101
+ background-size: 50px 50px;
102
+ animation: grid-move 20s linear infinite;
103
+ z-index: 0;
104
+ }
105
+
106
+ @keyframes grid-move {
107
+ 0% {
108
+ transform: translate(0, 0);
109
  }
110
  100% {
111
+ transform: translate(50px, 50px);
 
112
  }
113
  }
114
 
 
116
  position: relative;
117
  z-index: 1;
118
  text-align: center;
119
+ max-width: 900px;
120
  padding: 2rem;
121
+ animation: fadeIn 1s ease-out;
122
+ }
123
+
124
+ @keyframes fadeIn {
125
+ from {
126
+ opacity: 0;
127
+ }
128
+ to {
129
+ opacity: 1;
130
+ }
131
  }
132
 
133
  .logo-container {
134
  margin-bottom: 3rem;
135
+ animation: logoEntrance 1.2s cubic-bezier(0.34, 1.56, 0.64, 1) both;
136
+ }
137
+
138
+ @keyframes logoEntrance {
139
+ 0% {
140
+ opacity: 0;
141
+ transform: translateY(-50px) scale(0.5) rotate(-180deg);
142
+ }
143
+ 100% {
144
+ opacity: 1;
145
+ transform: translateY(0) scale(1) rotate(0deg);
146
+ }
147
+ }
148
+
149
+ .logo-wrapper {
150
+ position: relative;
151
+ display: inline-block;
152
+ margin-bottom: 2rem;
153
  }
154
 
155
  .logo {
156
+ width: 140px;
157
+ height: 140px;
158
+ margin: 0 auto;
159
+ background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple), var(--accent-pink));
160
+ border-radius: 32px;
161
  display: flex;
162
  align-items: center;
163
  justify-content: center;
164
  box-shadow:
165
+ 0 20px 60px rgba(45, 212, 191, 0.4),
166
+ 0 0 100px rgba(129, 140, 248, 0.3),
167
+ inset 0 0 60px rgba(255, 255, 255, 0.1);
168
+ animation: logoFloat 4s ease-in-out infinite, logoPulse 3s ease-in-out infinite;
169
  position: relative;
170
+ overflow: hidden;
171
  }
172
 
173
  .logo::before {
174
  content: '';
175
  position: absolute;
176
  inset: -4px;
177
+ background: linear-gradient(135deg, var(--accent-cyan), var(--accent-purple), var(--accent-pink));
178
+ border-radius: 36px;
179
+ opacity: 0.5;
180
+ filter: blur(30px);
181
+ animation: logoGlow 2s ease-in-out infinite;
182
+ z-index: -1;
183
  }
184
 
185
+ .logo::after {
186
+ content: '';
187
+ position: absolute;
188
+ inset: 0;
189
+ background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.3) 50%, transparent 70%);
190
+ animation: logoShine 3s ease-in-out infinite;
191
  }
192
 
193
+ @keyframes logoFloat {
194
  0%, 100% {
195
+ transform: translateY(0px) rotate(0deg);
196
+ }
197
+ 25% {
198
+ transform: translateY(-15px) rotate(2deg);
199
  }
200
  50% {
201
+ transform: translateY(-25px) rotate(0deg);
202
+ }
203
+ 75% {
204
+ transform: translateY(-15px) rotate(-2deg);
205
  }
206
  }
207
 
208
+ @keyframes logoPulse {
209
  0%, 100% {
 
210
  transform: scale(1);
211
  }
212
  50% {
 
213
  transform: scale(1.05);
214
  }
215
  }
216
 
217
+ @keyframes logoGlow {
218
+ 0%, 100% {
219
+ opacity: 0.3;
220
+ transform: scale(1);
221
+ }
222
+ 50% {
223
+ opacity: 0.6;
224
+ transform: scale(1.1);
225
+ }
226
+ }
227
+
228
+ @keyframes logoShine {
229
+ 0% {
230
+ transform: translateX(-100%) translateY(-100%) rotate(45deg);
231
+ }
232
+ 100% {
233
+ transform: translateX(200%) translateY(200%) rotate(45deg);
234
+ }
235
+ }
236
+
237
+ .logo svg {
238
+ position: relative;
239
+ z-index: 2;
240
+ filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5));
241
+ animation: svgRotate 8s linear infinite;
242
+ }
243
+
244
+ @keyframes svgRotate {
245
+ 0% {
246
+ transform: rotate(0deg);
247
+ }
248
+ 100% {
249
+ transform: rotate(360deg);
250
+ }
251
+ }
252
+
253
+ h1 {
254
+ font-family: 'Space Grotesk', sans-serif;
255
+ font-size: 4rem;
256
+ font-weight: 700;
257
+ margin-bottom: 1.5rem;
258
+ background: linear-gradient(135deg, var(--accent-cyan) 0%, var(--accent-purple) 50%, var(--accent-pink) 100%);
259
+ background-size: 200% 200%;
260
+ -webkit-background-clip: text;
261
+ background-clip: text;
262
+ -webkit-text-fill-color: transparent;
263
+ animation: fadeInDown 1s ease-out 0.3s both, gradientShift 5s ease infinite;
264
+ letter-spacing: -0.02em;
265
+ }
266
+
267
+ @keyframes gradientShift {
268
+ 0%, 100% {
269
+ background-position: 0% 50%;
270
+ }
271
+ 50% {
272
+ background-position: 100% 50%;
273
+ }
274
+ }
275
+
276
  @keyframes fadeInDown {
277
  from {
278
  opacity: 0;
 
284
  }
285
  }
286
 
287
+ .subtitle {
288
+ color: var(--text-secondary);
289
+ font-size: 1.4rem;
290
+ margin-bottom: 4rem;
291
+ line-height: 1.6;
292
+ animation: fadeInUp 1s ease-out 0.5s both;
293
+ }
294
+
295
  @keyframes fadeInUp {
296
  from {
297
  opacity: 0;
 
303
  }
304
  }
305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  .features {
307
  display: grid;
308
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
309
+ gap: 2rem;
310
+ margin-bottom: 4rem;
311
+ animation: fadeInUp 1s ease-out 0.7s both;
312
  }
313
 
314
  .feature {
315
+ padding: 2rem 1.5rem;
316
+ background: rgba(255, 255, 255, 0.05);
317
+ border: 1px solid rgba(255, 255, 255, 0.1);
318
+ border-radius: 20px;
319
+ backdrop-filter: blur(20px);
320
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
321
+ position: relative;
322
+ overflow: hidden;
323
+ }
324
+
325
+ .feature::before {
326
+ content: '';
327
+ position: absolute;
328
+ inset: 0;
329
+ background: linear-gradient(135deg, rgba(45, 212, 191, 0.1), rgba(129, 140, 248, 0.1));
330
+ opacity: 0;
331
+ transition: opacity 0.4s ease;
332
  }
333
 
334
  .feature:hover {
335
+ background: rgba(255, 255, 255, 0.08);
336
  border-color: var(--accent-cyan);
337
+ transform: translateY(-8px) scale(1.02);
338
+ box-shadow: 0 20px 40px rgba(45, 212, 191, 0.2);
339
+ }
340
+
341
+ .feature:hover::before {
342
+ opacity: 1;
343
  }
344
 
345
  .feature-icon {
346
+ width: 64px;
347
+ height: 64px;
348
+ margin: 0 auto 1.5rem;
349
+ display: flex;
350
+ align-items: center;
351
+ justify-content: center;
352
+ background: linear-gradient(135deg, rgba(45, 212, 191, 0.2), rgba(129, 140, 248, 0.2));
353
+ border-radius: 16px;
354
+ position: relative;
355
+ animation: iconFloat 3s ease-in-out infinite;
356
+ }
357
+
358
+ .feature:nth-child(1) .feature-icon {
359
+ animation-delay: 0s;
360
+ }
361
+
362
+ .feature:nth-child(2) .feature-icon {
363
+ animation-delay: 0.5s;
364
+ }
365
+
366
+ .feature:nth-child(3) .feature-icon {
367
+ animation-delay: 1s;
368
+ }
369
+
370
+ .feature:nth-child(4) .feature-icon {
371
+ animation-delay: 1.5s;
372
+ }
373
+
374
+ @keyframes iconFloat {
375
+ 0%, 100% {
376
+ transform: translateY(0px);
377
+ }
378
+ 50% {
379
+ transform: translateY(-10px);
380
+ }
381
+ }
382
+
383
+ .feature-icon svg {
384
+ width: 32px;
385
+ height: 32px;
386
+ stroke: var(--accent-cyan);
387
+ filter: drop-shadow(0 0 8px rgba(45, 212, 191, 0.6));
388
+ animation: iconPulse 2s ease-in-out infinite;
389
+ }
390
+
391
+ @keyframes iconPulse {
392
+ 0%, 100% {
393
+ opacity: 1;
394
+ transform: scale(1);
395
+ }
396
+ 50% {
397
+ opacity: 0.8;
398
+ transform: scale(1.1);
399
+ }
400
  }
401
 
402
  .feature-text {
403
  color: var(--text-primary);
404
+ font-weight: 600;
405
+ font-size: 1rem;
406
+ position: relative;
407
+ z-index: 1;
408
  }
409
 
410
  .loading-section {
411
  margin-top: 3rem;
412
+ animation: fadeInUp 1s ease-out 0.9s both;
413
+ }
414
+
415
+ .progress-container {
416
+ width: 100%;
417
+ max-width: 500px;
418
+ margin: 0 auto 2rem;
419
  }
420
 
421
  .progress-bar {
422
  width: 100%;
423
+ height: 8px;
 
424
  background: rgba(255, 255, 255, 0.1);
425
  border-radius: 999px;
426
  overflow: hidden;
 
427
  position: relative;
428
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
429
  }
430
 
431
  .progress-fill {
432
  height: 100%;
433
  width: 0;
434
+ background: linear-gradient(90deg, var(--accent-cyan), var(--accent-purple), var(--accent-pink), var(--accent-cyan));
435
+ background-size: 200% 100%;
436
  border-radius: 999px;
437
+ animation: progress 2.5s ease-in-out forwards, gradientMove 3s linear infinite;
438
  position: relative;
439
+ box-shadow: 0 0 20px rgba(45, 212, 191, 0.5);
440
  }
441
 
442
  .progress-fill::after {
443
  content: '';
444
  position: absolute;
445
  top: 0;
446
+ left: 0;
447
  right: 0;
448
+ bottom: 0;
449
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
450
+ animation: shimmer 1.5s infinite;
 
451
  }
452
 
453
  @keyframes progress {
 
456
  }
457
  }
458
 
459
+ @keyframes gradientMove {
460
+ 0% {
461
+ background-position: 0% 0%;
462
+ }
463
+ 100% {
464
+ background-position: 200% 0%;
465
+ }
466
+ }
467
+
468
  @keyframes shimmer {
469
+ 0% {
470
+ transform: translateX(-100%);
471
+ }
472
+ 100% {
473
  transform: translateX(100%);
474
  }
475
  }
476
 
477
  .loading-text {
478
  color: var(--text-secondary);
479
+ font-size: 1.1rem;
480
+ margin-top: 1.5rem;
481
+ font-weight: 500;
482
+ min-height: 1.5rem;
483
+ animation: textPulse 2s ease-in-out infinite;
484
  }
485
 
486
+ @keyframes textPulse {
487
  0%, 100% {
488
+ opacity: 0.7;
489
  }
490
  50% {
491
  opacity: 1;
492
  }
493
  }
494
 
495
+ .skip-link {
496
+ display: inline-block;
497
+ margin-top: 2rem;
498
+ padding: 0.75rem 2rem;
499
+ color: var(--accent-cyan);
500
+ text-decoration: none;
501
+ font-weight: 600;
502
+ border: 2px solid rgba(45, 212, 191, 0.3);
503
+ border-radius: 50px;
504
+ transition: all 0.3s ease;
505
+ position: relative;
506
+ overflow: hidden;
507
+ }
508
+
509
+ .skip-link::before {
510
+ content: '';
511
+ position: absolute;
512
+ inset: 0;
513
+ background: linear-gradient(135deg, rgba(45, 212, 191, 0.1), rgba(129, 140, 248, 0.1));
514
+ transform: translateX(-100%);
515
+ transition: transform 0.3s ease;
516
+ }
517
+
518
+ .skip-link:hover {
519
+ border-color: var(--accent-cyan);
520
+ background: rgba(45, 212, 191, 0.1);
521
+ transform: translateY(-2px);
522
+ box-shadow: 0 10px 30px rgba(45, 212, 191, 0.3);
523
+ }
524
+
525
+ .skip-link:hover::before {
526
+ transform: translateX(0);
527
+ }
528
+
529
  .version {
530
  position: absolute;
531
  bottom: 2rem;
532
  right: 2rem;
533
  color: var(--text-secondary);
534
+ font-size: 0.9rem;
535
+ opacity: 0.6;
536
+ font-weight: 500;
537
  }
538
 
539
  @media (max-width: 768px) {
 
551
  }
552
 
553
  .feature {
554
+ padding: 1.5rem 1rem;
555
  }
556
 
557
+ .logo {
558
+ width: 120px;
559
+ height: 120px;
560
  }
561
 
562
+ .feature-icon {
563
+ width: 56px;
564
+ height: 56px;
565
  }
566
  }
567
  </style>
568
  </head>
569
  <body>
570
+ <!-- Animated gradient orbs -->
571
+ <div class="gradient-orbs">
572
+ <div class="orb orb-1"></div>
573
+ <div class="orb orb-2"></div>
574
+ <div class="orb orb-3"></div>
575
+ </div>
576
+
577
+ <!-- Animated grid background -->
578
+ <div class="grid-background"></div>
579
 
580
  <div class="container">
581
  <div class="logo-container">
582
+ <div class="logo-wrapper">
583
+ <div class="logo">
584
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
585
+ <path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="url(#gradient1)"></path>
586
+ <path d="M2 17L12 22L22 17" stroke="url(#gradient2)"></path>
587
+ <path d="M2 12L12 17L22 12" stroke="url(#gradient3)"></path>
588
+ <defs>
589
+ <linearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="100%">
590
+ <stop offset="0%" style="stop-color:#2dd4bf;stop-opacity:1" />
591
+ <stop offset="100%" style="stop-color:#818cf8;stop-opacity:1" />
592
+ </linearGradient>
593
+ <linearGradient id="gradient2" x1="0%" y1="0%" x2="100%" y2="100%">
594
+ <stop offset="0%" style="stop-color:#818cf8;stop-opacity:1" />
595
+ <stop offset="100%" style="stop-color:#ec4899;stop-opacity:1" />
596
+ </linearGradient>
597
+ <linearGradient id="gradient3" x1="0%" y1="0%" x2="100%" y2="100%">
598
+ <stop offset="0%" style="stop-color:#ec4899;stop-opacity:1" />
599
+ <stop offset="100%" style="stop-color:#2dd4bf;stop-opacity:1" />
600
+ </linearGradient>
601
+ </defs>
602
+ </svg>
603
+ </div>
604
  </div>
605
  </div>
606
 
 
611
 
612
  <div class="features">
613
  <div class="feature">
614
+ <div class="feature-icon">
615
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
616
+ <line x1="18" y1="20" x2="18" y2="10"></line>
617
+ <line x1="12" y1="20" x2="12" y2="4"></line>
618
+ <line x1="6" y1="20" x2="6" y2="14"></line>
619
+ </svg>
620
+ </div>
621
  <div class="feature-text">Real-time Market Data</div>
622
  </div>
623
  <div class="feature">
624
+ <div class="feature-icon">
625
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
626
+ <path d="M12 2v10"></path>
627
+ <path d="M18.4 6.6a9 9 0 1 1-12.77.04"></path>
628
+ <path d="M12 12l-8 8"></path>
629
+ <path d="M12 12l8 8"></path>
630
+ </svg>
631
+ </div>
632
  <div class="feature-text">AI-Powered Analysis</div>
633
  </div>
634
  <div class="feature">
635
+ <div class="feature-icon">
636
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
637
+ <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
638
+ </svg>
639
+ </div>
640
  <div class="feature-text">Technical Indicators</div>
641
  </div>
642
  <div class="feature">
643
+ <div class="feature-icon">
644
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
645
+ <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path>
646
+ <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
647
+ </svg>
648
+ </div>
649
  <div class="feature-text">Smart Alerts</div>
650
  </div>
651
  </div>
652
 
653
  <div class="loading-section">
654
+ <div class="progress-container">
655
+ <div class="progress-bar">
656
+ <div class="progress-fill"></div>
657
+ </div>
658
  </div>
659
  <div class="loading-text" id="loadingText">
660
  Initializing platform...
661
  </div>
662
  <a href="/static/pages/dashboard/index.html"
663
  onclick="sessionStorage.setItem('skipSplash', 'true');"
664
+ class="skip-link">
665
  Skip to Dashboard →
666
  </a>
667
  </div>
 
670
  <div class="version">v1.0.0</div>
671
 
672
  <script>
673
+ // Loading messages with smooth transitions
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  const loadingMessages = [
675
  'Initializing platform...',
676
  'Loading market data...',
 
683
  const loadingText = document.getElementById('loadingText');
684
 
685
  const messageInterval = setInterval(() => {
686
+ if (currentMessage < loadingMessages.length - 1) {
687
+ currentMessage++;
688
+ loadingText.style.opacity = '0';
689
+ setTimeout(() => {
690
+ loadingText.textContent = loadingMessages[currentMessage];
691
+ loadingText.style.opacity = '1';
692
+ }, 200);
693
  }
694
+ }, 500);
695
 
696
+ // Redirect to dashboard after animation
697
  setTimeout(() => {
698
  clearInterval(messageInterval);
699
+ loadingText.style.opacity = '0';
700
+ setTimeout(() => {
701
+ loadingText.textContent = 'Welcome! 🚀';
702
+ loadingText.style.opacity = '1';
703
+ }, 200);
704
 
705
  // Save preference to skip splash next time
706
  sessionStorage.setItem('skipSplash', 'true');
707
 
708
  setTimeout(() => {
709
  window.location.href = '/static/pages/dashboard/index.html';
710
+ }, 500);
711
+ }, 2500);
712
  </script>
713
  </body>
714
  </html>