feat: merge github/main, deploy Google Trust & Safety verified privacy and terms with clean vercel routes

This commit is contained in:
2026-10-04 01:07:35 +00:00
19 changed files with 3561 additions and 446 deletions
+2
View File
@@ -2,3 +2,5 @@
Thumbs.db
*.log
node_modules/
.vercel
+5
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

+25
View File
@@ -0,0 +1,25 @@
services:
web:
build:
context: .
dockerfile: Dockerfile
networks:
- coolify
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.auraajenticai-http.entrypoints=http"
- "traefik.http.routers.auraajenticai-http.rule=Host(`auraajenticai.cloud`)"
- "traefik.http.routers.auraajenticai-http.middlewares=redirect-to-https"
- "traefik.http.routers.auraajenticai-https.entrypoints=https"
- "traefik.http.routers.auraajenticai-https.rule=Host(`auraajenticai.cloud`)"
- "traefik.http.routers.auraajenticai-https.tls=true"
- "traefik.http.routers.auraajenticai-https.tls.certresolver=letsencrypt"
- "traefik.http.services.auraajenticai.loadbalancer.server.port=80"
- "coolify.managed=true"
restart: unless-stopped
networks:
coolify:
external: true
+464
View File
@@ -0,0 +1,464 @@
# Aura Agentic AI Cloud — MASTER.md
> Single source of truth for the entire infrastructure.
> **Last updated:** 2026-05-02 | **VPS:** root@195.35.7.154
> ⚠ Credentials are referenced by location only — never pasted here.
---
## 1. VPS
| Field | Value |
|-------|-------|
| Provider | Hostinger KVM 2 |
| Hostname | srv1540635.hstgr.cloud |
| IP | 195.35.7.154 |
| OS | Ubuntu 24.04.4 LTS |
| Kernel | 6.8.0-110-generic x86-64 |
| CPU | 2× vCPU (AMD EPYC, KVM) |
| RAM | 7.8 GB (4.2 GB used) |
| Disk | 96 GB SSD (36 GB used · 61 GB free · 38%) |
| Swap | 4 GB (256 KB used) |
| SSH Key | C:\Users\Masud\.ssh\id_ed25519 |
---
## 2. Live Services & URLs
### Coolify Services
| UUID | Service | URL | Status |
|------|---------|-----|--------|
| `dhcia3tgcvwmwwvexznjw9gr` | OpenClaw (Primary Agent) | https://agent.auraajenticai.cloud | ✅ Healthy |
| `m10jif2sbykx4hd33qf97hc6` | OpenClaw (Secondary / App) | https://app.auraajenticai.cloud | ✅ Healthy |
| `j9pqq74tuik1oqd5runx5ncb` | n8n + PostgreSQL + Task Runners | https://n8n.auraajenticai.cloud | ✅ Healthy |
| `oqwgsn2lcv3hsk13c6ayj8du` | Gitea + PostgreSQL | https://git.auraajenticai.cloud | ✅ Healthy |
### Coolify Applications
| UUID | App | URL | Commit | Status |
|------|-----|-----|--------|--------|
| `q2kkhvkrpdm6ukj20gv69tuk` | Public Site | https://auraajenticai.cloud | a2a11b4 | ⚠ Pending pull (demo URLs commit not yet applied via Coolify) |
| `g5ehpyu7i1azk7f1sv1bhctz` | Central Auth | https://auth.auraajenticai.cloud | 923435bf | ✅ Up |
| `m43q7n7vlttrzyxy5v2hkaig` | API Gateway | https://api.auraajenticai.cloud | 8c2045a7 | ✅ Up |
| `rdqk1mqe0k8fifs64d7jrzfi` | Client Portal | https://client.auraajenticai.cloud | 03a90610 | ✅ Up |
| `j8xnv56xhx6wiaeal2bfiktm` | Billing | https://billing.auraajenticai.cloud | fd9aa384 | ✅ Up |
| `zu9kxa9iung19q003ybvcdj3` | Owner Dashboard | https://aura.auraajenticai.cloud | 2b652dba | ✅ Up |
| `m6fnc3kfy72tf77anuv4o2f4` | [Internal — UUID subdomain] | https://m6fnc3kfy72tf77anuv4o2f4.auraajenticai.cloud | 3df7af00 | ✅ Up |
| `rul16lgnv650ic5kv5wgd51h` | [Staging — no FQDN] | — | 03a90610 | — |
| `y22x4z5sxh3854tbmiv98s2j` | [Staging — no FQDN] | — | 03a90610 | — |
| `z24up798jcmaf4biwshx2kv5` | [Staging — no FQDN] | — | — | — |
### Coolify System
| Service | URL |
|---------|-----|
| Coolify Dashboard | https://coolify.auraajenticai.cloud (port 8000 local) |
| Traefik Dashboard | http://195.35.7.154:8080/dashboard/ ⚠ publicly accessible |
| Coolify Version | 4.0.0-beta.473 (Laravel 12.55.1) |
| Traefik Version | v3.6 |
---
## 3. Complete Tech Stack
### Infrastructure
- **Reverse Proxy:** Traefik v3.6 (HTTP :80 → HTTPS :443, Let's Encrypt cert resolver)
- **Orchestration:** Coolify 4.0.0-beta.473 (self-hosted)
- **Git:** Gitea v1.26.0 (SSH :22222, HTTP git.auraajenticai.cloud)
- **Containers:** Docker + Docker Compose
- **OS:** Ubuntu 24.04.4 LTS
### AI / Agents
- **Agent Runtime:** OpenClaw v2026.2.6
- **Primary Model:** `openrouter/anthropic/claude-sonnet-4.5`
- **AI Provider:** OpenRouter (key in Coolify .env)
- **Additional Providers:** Google Gemini (GEMINI_API_KEY set), Groq (GROQ_API_KEY set)
- **Channels:** Telegram (@tradingbanglaajentic_bot — long-polling)
- **Agent Tools:** read, edit, write, exec, browser, canvas, nodes, cron, message, sessions, web_search, memory
### Automation
- **n8n:** v2.10.2 + Task Runners 2.10.2
- **Webhooks:** https://n8n.auraajenticai.cloud/webhook/*
### Frontend
- **Public Site:** React 18 + Babel Standalone (CDN, no build step)
- **Dashboard/Apps:** SvelteKit 2 + Svelte 5 runes + Tailwind CSS + Vite
- **Fonts:** Geist, Geist Mono, Instrument Serif (Google Fonts)
### Backend
- **Auth Service:** Hono + Drizzle ORM + JWT + bcrypt (SvelteKit adapter-node)
- **API:** Node.js / Hono
- **Language:** TypeScript throughout
### Databases
| DB | Container | Engine | Database Name | Network IP |
|----|-----------|--------|---------------|------------|
| Auth/Main | `ernix50nvuq9ur9jy8na8tgr` | Supabase Postgres 17.4 | `aura_auth` | 10.0.1.7:5432 |
| n8n | `postgresql-j9pqq74tuik1oqd5runx5ncb` | Postgres 16-alpine | `n8n` | internal |
| Gitea | `postgresql-oqwgsn2lcv3hsk13c6ayj8du` | Postgres 16-alpine | `gitea` | internal |
| Coolify | `coolify-db` | Postgres 15-alpine | `coolify` | internal |
| Document | `b3bhfd7bocb4pm36uv36rebq` | MongoDB 7 | *(various)* | :27017 |
| Cache | `coolify-redis` | Redis 7-alpine | — | internal |
### aura_auth DB Schema
Tables: `users`, `sessions`, `api_keys`, `audit_logs`, `clients`, `projects`, `skills`, `invoices`
---
## 4. OpenClaw Configuration (Primary — `dhcia3tgcvwmwwvexznjw9gr`)
```
AI Provider: OpenRouter
Primary Model: openrouter/anthropic/claude-sonnet-4.5
Secondary Model: anthropic/claude-3.5-haiku (env var, secondary/fast not in schema)
Fast Model: anthropic/claude-3-haiku (env var)
Gateway: ws://127.0.0.1:18789 (loopback, behind nginx on :8080)
Auth mode: token (OPENCLAW_GATEWAY_TOKEN)
nginx auth: SERVICE_USER_OPENCLAW / SERVICE_PASSWORD_OPENCLAW
```
### Telegram Channel
```
Bot username: @tradingbanglaajentic_bot
Bot ID: 8736690733
Mode: long-polling (no webhook URL set)
Status: enabled, configured, running
Channel name: default
Token env: TELEGRAM_BOT_TOKEN (in Coolify service .env)
```
> To test: send any message to @tradingbanglaajentic_bot on Telegram.
> OpenClaw routes it to the main agent session → claude-sonnet-4.5 → reply back.
### Workspace Files
Located at: `/var/lib/docker/volumes/dhcia3tgcvwmwwvexznjw9gr_openclaw-data/_data/workspace/`
| File | Purpose |
|------|---------|
| AGENTS.md | Agent routing rules and capabilities |
| BOOTSTRAP.md | Startup context injected every session |
| HEARTBEAT.md | Scheduled check-in instructions |
| IDENTITY.md | Agent persona and identity rules |
| SOUL.md | Core values and behavioral constraints |
| TOOLS.md | Available tool descriptions |
| USER.md | User (Khondokar) profile and preferences |
---
## 5. n8n Workflows
URL: https://n8n.auraajenticai.cloud
Contact webhook: `POST https://n8n.auraajenticai.cloud/webhook/contact`
| Workflow ID | Name |
|-------------|------|
| `j2JZuCcx38n6hFUa` | skill-code-review |
| `ICKS1V8j0rfFRCAM` | skill-analyze |
| `tza1cNW0fCZhMd63` | skill-draft-email |
| `1FtaniVPKRBKNDwX` | invoice-overdue-checker |
| `MeuMN9zV0m2SlPeV` | skill-summarize |
| `l2CkZKPgnSyt3Nvt` | Generate AI viral videos (NanoBanana + VEO3 → Blotato) |
| `zLqHh5sJ6rT7lyGU` | new-client-deployment |
| `sX0KPnr4c0Zh138d` | contact-form |
| `8kjRU6YNvtJpcpTD` | client-onboarding |
| `m4AB1XlfpvgmNmLF` | api-usage-weekly-report |
---
## 6. Gitea Repositories
Host: https://git.auraajenticai.cloud
User: `khondokar`
Token location: `C:\Users\Masud\.claude\projects\C--Users-Masud-aura\memory\project_aura_infrastructure.md`
| Repo | URL | Last Updated |
|------|-----|-------------|
| khondokar/auraajenticai-main | git.auraajenticai.cloud/khondokar/auraajenticai-main | 2026-04-27 |
### GitHub Mirrors (github.com/khondokartowsif171)
| Repo | GitHub URL | Notes |
|------|-----------|-------|
| auraajenticai-main | github.com/khondokartowsif171/auraajenticai-main | Main site — latest commit a2a11b4 (demo URLs) |
| demo-autostudio-ecomercewebsite | github.com/khondokartowsif171/demo-autostudio-ecomercewebsite | Vite/React ecommerce |
| demo-agenticai-website | github.com/khondokartowsif171/demo-agenticai-website | Static HTML portfolio |
| demo-cryptotradeanalysis-website | github.com/khondokartowsif171/demo-cryptotradeanalysis-website | React crypto dashboard |
| demo-ea-dashboard | github.com/khondokartowsif171/demo-ea-dashboard | Static HTML XAUUSD analyzer |
| demo-portfolio-website | github.com/khondokartowsif171/demo-portfolio-website | Vite/React portfolio |
---
## 7. Important File Paths
### On VPS (root@195.35.7.154)
```
/docs/MASTER.md ← this file
# Coolify data root
/data/coolify/applications/{uuid}/ ← per-app: .env + docker-compose.yaml
/data/coolify/services/{uuid}/ ← per-service: .env + docker-compose.yaml
/data/coolify/proxy/ ← Traefik dynamic config
/data/coolify/ssh/ ← SSH keys for deployments
# OpenClaw Primary (dhcia3tgcvwmwwvexznjw9gr)
/var/lib/docker/volumes/dhcia3tgcvwmwwvexznjw9gr_openclaw-data/_data/
.openclaw/openclaw.json ← main config (auto-managed by entrypoint)
.openclaw/openclaw.json.bak ← backup (up to 4 kept)
.openclaw/credentials/ ← API keys/tokens (never edit directly)
.openclaw/agents/main/sessions/sessions.json ← conversation history
workspace/ ← agent workspace (AGENTS.md, SOUL.md, etc.)
# Service .env files (credentials)
/data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env ← OpenClaw primary
/data/coolify/services/m10jif2sbykx4hd33qf97hc6/.env ← OpenClaw secondary
/data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env ← n8n + DB
/data/coolify/services/oqwgsn2lcv3hsk13c6ayj8du/.env ← Gitea
/data/coolify/applications/{uuid}/.env ← per-app credentials
```
### On Local (Windows — C:\Users\Masud\)
```
.ssh/id_ed25519 ← VPS SSH private key
.claude/settings.json ← MCP servers + API keys
.claude/projects/C--Users-Masud-aura/
memory/MEMORY.md ← Memory index
memory/project_aura_infrastructure.md ← Infra notes (has tokens)
memory/user_khondokar.md ← Founder profile
aura/
auraajenticai-main/ ← Public site source (git)
src/data.jsx ← All content + brand data
src/nav.jsx ← Navigation + lang toggle
src/hero.jsx ← Hero section
src/app.jsx ← Root app + lang state
src/projects.jsx ← Services grid (6 cards)
src/timeline-contact.jsx ← Timeline, contact form, footer
src/agent-showcase.jsx ← Agent demo terminal
index.html ← Entry point + CSS vars
Dockerfile ← nginx:1.27-alpine
nginx.conf ← JSX MIME fix + gzip + SPA
aura-dashboard/ ← Owner Dashboard (SvelteKit 2)
n8n-mcp/index.js ← Custom n8n MCP server
```
---
## 8. Credentials Locations (NOT values)
| Credential | Location |
|-----------|---------|
| VPS root password | Hostinger dashboard (hostinger.com) |
| SSH private key | C:\Users\Masud\.ssh\id_ed25519 |
| Coolify API token | memory/project_aura_infrastructure.md |
| Gitea token (khondokar) | memory/project_aura_infrastructure.md |
| OpenRouter API key | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → OPENROUTER_API_KEY |
| Telegram bot token | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → TELEGRAM_BOT_TOKEN |
| OpenClaw gateway token | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → SERVICE_PASSWORD_64_GATEWAYTOKEN |
| OpenClaw nginx auth | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → SERVICE_USER/PASSWORD_OPENCLAW |
| Gemini API key | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → GEMINI_API_KEY |
| Groq API key | /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr/.env → GROQ_API_KEY |
| n8n admin credentials | /data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env |
| Cloudflare token (n8n) | /data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env → CLOUDFLARE_TOKEN |
| Cloudflare Zone ID | /data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env → CLOUDFLARE_ZONE_ID |
| Supabase DB password | /data/coolify/databases/ernix50nvuq9ur9jy8na8tgr/ or service .env |
| MongoDB auth | /data/coolify/databases/b3bhfd7bocb4pm36uv36rebq/ |
| JWT secret (shared) | application UUID g5ehpyu7... .env |
| aura_auth DB password | application UUIDs (dashboard apps) .env → DATABASE_URL |
| Claude Code API key | C:\Users\Masud\.claude\settings.json |
| n8n MCP API key | C:\Users\Masud\.claude\settings.json |
---
## 9. MCP Tools Status
Configured in: `C:\Users\Masud\.claude\settings.json`
| MCP Server | Status | Key Tools |
|-----------|--------|-----------|
| **Coolify** (`04a4937c-...`) | ✅ Connected | d1_database_*, kv_namespace_*, r2_bucket_*, workers_* |
| **Gitea** | ✅ Connected | issue_*, pull_request_*, repo_*, user_* |
| **n8n** (local node server) | ✅ Connected | list_workflows, execute_workflow, set_workflow_active |
| **Google Calendar** (`c00adf3f-...`) | ✅ Connected | list_events, create_event, update_event |
| **Gmail** (`0525003c-...`) | ✅ Connected | search_threads, get_thread, create_draft |
| **Google Drive** (`d51cbec6-...`) | ✅ Connected | read_file_content, search_files, create_file |
| **Vercel** (`39a5e89f-...`) | ✅ Connected | list_projects, list_deployments, get_runtime_logs |
| **Claude Preview** | ✅ Available | preview_start, preview_screenshot, preview_eval |
| **Computer Use** | ✅ Available | screenshot, left_click, type, key, scroll |
| **Claude-in-Chrome** | ✅ Available | navigate, find, read_page, javascript_tool |
---
## 10. Phase Completion Status
| Phase | Description | Status | Completed |
|-------|-------------|--------|-----------|
| **0** | VPS audit, health report, swap configured, baseline | ✅ Complete | 2026-04-26 |
| **1** | Central Auth Service (SvelteKit + Hono + Drizzle + JWT + bcrypt) | ✅ Complete | 2026-04-26 |
| **2** | Owner Dashboard upgrade (sidebar nav, auth gate, Clients CRUD, Brain Console) | ✅ Complete | 2026-04-27 |
| **3** | Public site (auraajenticai.cloud) — bilingual EN/BN, 6 services, n8n contact form | ✅ Complete | 2026-04-27 |
| **4** | OpenClaw AI Agent — OpenRouter + claude-sonnet-4.5 + model ID fix | ✅ Complete | 2026-04-30 |
| **5** | Telegram integration — @tradingbanglaajentic_bot wired to OpenClaw agent | ✅ Complete | 2026-05-01 |
| **6** | Client portal (client.auraajenticai.cloud) | ✅ Deployed | — |
| **7** | API gateway (api.auraajenticai.cloud) | ✅ Deployed | — |
| **8** | Billing service (billing.auraajenticai.cloud) | ✅ Deployed | — |
| **9** | n8n automation (10 workflows: skills, contact, onboarding, invoice, AI video) | ✅ Active | — |
| **10** | DB backups, monitoring, Traefik hardening, OpenClaw secondary model config | ⏳ Pending | — |
| **11** | Demo projects — 5 Vercel deployments, GitHub repos, live demo buttons on public site | ✅ Complete | 2026-05-02 |
---
## 11. Pending / Known Gaps
### High Priority
- [ ] **Phase 10:** Automated DB backups (no crontab yet — data loss risk)
- [ ] **Traefik dashboard** `:8080` is publicly accessible — restrict to VPN/IP allowlist
- [ ] **OpenClaw secondary** (`app.auraajenticai.cloud` — `m10jif2sbykx4hd33qf97hc6`) has no `OPENCLAW_PRIMARY_MODEL` set
- [ ] **ANTHROPIC_API_KEY** not set in Owner Dashboard app (required for Brain Console feature)
- [ ] **Telegram live test** — send `/start` to @tradingbanglaajentic_bot to verify full round-trip
- [ ] **Public site — pull & rebuild** — commit `a2a11b4` (demo URLs) is on GitHub but NOT yet pulled into VPS/Coolify. Run from Hostinger console (see §13)
- [ ] **Cloudflare DNS** — `auraajenticai.cloud` A record still points to VPS (195.35.7.154). Vercel domain added (`auraajenticai-main` project) but DNS not yet switched. Need `A → 76.76.21.21` + `www CNAME → cname.vercel-dns.com`. Cloudflare token at `/data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env → CLOUDFLARE_TOKEN`
### Medium Priority
- [ ] Set up disk/memory monitoring (no alerting configured)
- [ ] Configure Traefik rate limiting on API gateway
- [ ] Gitea webhook → Coolify auto-deploy (currently triggered manually)
- [ ] n8n workflow active/inactive status audit (10 workflows, status not confirmed per-item)
- [ ] MongoDB — confirm root credentials and access restriction
### Low Priority
- [ ] `www.auraajenticai.cloud` CNAME redirect to apex
- [ ] Log retention policy for OpenClaw gateway logs (`/tmp/openclaw/`)
- [ ] Document aura_auth DB migration history
- [ ] Add `app.auraajenticai.cloud` source repo to Gitea
---
## 12. Auth Service Details
```
URL: https://auth.auraajenticai.cloud
Container UUID: g5ehpyu7i1azk7f1sv1bhctz
Container IP: 10.0.1.12
Framework: SvelteKit + Hono + Drizzle + JWT + bcrypt
DB: Supabase Postgres 17.4 @ 10.0.1.7:5432/aura_auth
Cookies:
aura_access → 15-min JWT
aura_refresh → 7-day (path /api/auth/refresh)
Cookie domain: .auraajenticai.cloud
Login URL: https://auth.auraajenticai.cloud/login?next=<URL>
```
---
## 13. Quick Reference Commands
```bash
# SSH to VPS
ssh root@195.35.7.154
# All containers + status
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}'
# OpenClaw — live logs (primary)
docker logs openclaw-dhcia3tgcvwmwwvexznjw9gr --tail=30 -f
# OpenClaw — test agent
docker exec openclaw-dhcia3tgcvwmwwvexznjw9gr \
openclaw agent --message "ping" --session-id main --json
# OpenClaw — Telegram channel status
docker exec openclaw-dhcia3tgcvwmwwvexznjw9gr openclaw channels status
# OpenClaw — restart with updated env
cd /data/coolify/services/dhcia3tgcvwmwwvexznjw9gr
docker compose up openclaw --force-recreate -d
# n8n — list workflows
docker exec n8n-j9pqq74tuik1oqd5runx5ncb n8n list:workflow
# Disk usage
df -h / && du -sh /var/lib/docker/volumes/*openclaw* /data/coolify/
# Check all service domains
for d in /data/coolify/services/*/; do
uuid=$(basename $d)
fqdn=$(grep SERVICE_FQDN= $d/.env 2>/dev/null | cut -d= -f2)
echo "$uuid: $fqdn"
done
```
---
---
## 14. Vercel Deployments (2026-05-02)
Team: `khondokartowsif171s-projects` (`team_9DzpWOXgLFfZkFhpYL0QoKAO`)
| Project | Live URL | GitHub Repo | Notes |
|---------|----------|-------------|-------|
| auraajenticai-main | https://auraajenticai-main.vercel.app | khondokartowsif171/auraajenticai-main | Main site — domain `auraajenticai.cloud` added to project, DNS not yet switched |
| demo-autostudio-ecomercewebsite | https://demo-autostudio-ecomercewebsite.vercel.app | khondokartowsif171/demo-autostudio-ecomercewebsite | Linked to service card: Website & Webapp Dev |
| demo-agenticai-website | https://demo-agenticai-website.vercel.app | khondokartowsif171/demo-agenticai-website | Linked to: AI Agent & Automation |
| demo-cryptotradeanalysis-website | https://demo-cryptotradeanalysis-website.vercel.app | khondokartowsif171/demo-cryptotradeanalysis-website | Linked to: Web3 & Blockchain |
| ea-dashboard | https://ea-dashboard-blush.vercel.app | khondokartowsif171/demo-ea-dashboard | Linked to: MT5 EA & Trading |
| portfolio-website | https://portfolio-website-tan-six-24.vercel.app | khondokartowsif171/demo-portfolio-website | Linked to: Scraping & Data Pipeline |
### Demo URL → Service Card Mapping (`src/data.jsx`)
```
web-app-dev → https://demo-autostudio-ecomercewebsite.vercel.app
ai-agent-automation → https://demo-agenticai-website.vercel.app
web3-blockchain → https://demo-cryptotradeanalysis-website.vercel.app
mt5-ea-trading → https://ea-dashboard-blush.vercel.app
scraping-data-pipeline → https://portfolio-website-tan-six-24.vercel.app
infra-devops → (no demo — button hidden)
```
---
## 15. VPS Console Commands (run from Hostinger web console)
Use when SSH from local machine is blocked by network routing issues.
```bash
# Pull latest main site source from GitHub into Coolify app dir
cd /data/coolify/applications/q2kkhvkrpdm6ukj20gv69tuk
git remote get-url github 2>/dev/null || \
git remote add github https://github.com/khondokartowsif171/auraajenticai-main.git
git pull github main
# Also push to Gitea to keep it in sync
git push origin main
# Trigger Coolify rebuild for the public site
curl -s -X POST http://localhost:8000/api/v1/applications/q2kkhvkrpdm6ukj20gv69tuk/start \
-H "Authorization: Bearer 6|aura-claude-ceo-2026-secret"
# Get Cloudflare token + zone ID for DNS update
grep -E "CLOUDFLARE_TOKEN|CLOUDFLARE_ZONE_ID" \
/data/coolify/services/j9pqq74tuik1oqd5runx5ncb/.env
# Update Cloudflare DNS: point auraajenticai.cloud to Vercel (76.76.21.21)
# Replace ZONE_ID and TOKEN with values from above
CF_ZONE="ZONE_ID_HERE"
CF_TOKEN="TOKEN_HERE"
# Get existing A record ID
curl -s "https://api.cloudflare.com/client/v4/zones/$CF_ZONE/dns_records?type=A&name=auraajenticai.cloud" \
-H "Authorization: Bearer $CF_TOKEN" | grep -o '"id":"[^"]*"' | head -1
# Update it (replace RECORD_ID)
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CF_ZONE/dns_records/RECORD_ID" \
-H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
-d '{"type":"A","name":"auraajenticai.cloud","content":"76.76.21.21","ttl":1,"proxied":true}'
# Add www CNAME
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE/dns_records" \
-H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
-d '{"type":"CNAME","name":"www","content":"cname.vercel-dns.com","ttl":1,"proxied":false}'
```
---
*Generated by Claude (Aura AI Brain) on 2026-05-01. Updated 2026-05-02. Update this file after each infrastructure change.*
+161 -16
View File
@@ -3,16 +3,155 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Aura Agentic AI — AI Agents, Automation & Full-Stack Dev</title>
<meta name="description" content="Aura Agentic AI builds custom AI agents, automation pipelines, Web3 infrastructure, MT5 trading systems, data pipelines, and enterprise web apps — based in Dhaka, serving clients worldwide." />
<meta name="keywords" content="AI agents, automation, SvelteKit, n8n, Anthropic, Web3, MT5 EA, web development, Bangladesh" />
<meta property="og:title" content="Aura Agentic AI — AI Agents, Automation & Full-Stack Dev" />
<title>Aura Ajentic AI — Autonomous AI Sales Agents, Courier MCP & COD Fraud Shield</title>
<meta name="description" content="Aura is a B2B AI SaaS platform empowering e-commerce businesses with autonomous conversational AI agents, Bangladesh's first Courier MCP logistics engine, and real-time COD fraud defense." />
<meta name="keywords" content="AI agents, automation, SvelteKit, n8n, Google Gemini, Vertex AI, Web3, MT5 EA, web development, Bangladesh" />
<meta property="og:title" content="Aura Ajentic AI — AI Agents, Automation & Full-Stack Dev" />
<meta property="og:description" content="We build AI agents, automation & enterprise systems that work 24/7." />
<meta property="og:url" content="https://auraajenticai.cloud" />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://auraajenticai.cloud/logo.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Aura Agentic AI" />
<meta name="twitter:title" content="Aura Ajentic AI" />
<meta name="twitter:description" content="AI agents, automation & full-stack development — Dhaka, Bangladesh." />
<meta name="twitter:image" content="https://auraajenticai.cloud/logo.png" />
<link rel="canonical" href="https://auraajenticai.cloud" />
<link rel="icon" type="image/png" href="logo.png" />
<link rel="apple-touch-icon" href="logo.png" />
<meta name="google-site-verification" content="vEK4vy89hAbckU9sUlqn7mZlMxLjNT--CvuLruocMfQ" />
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-WMF863QM');</script>
<!-- End Google Tag Manager -->
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-5MB0V1M3LQ"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-5MB0V1M3LQ');
</script>
<!-- Plausible Analytics -->
<script defer data-domain="auraajenticai.cloud" src="https://plausible.io/js/script.js"></script>
<!-- JSON-LD: Organization -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Aura Ajentic AI",
"url": "https://auraajenticai.cloud",
"logo": "https://auraajenticai.cloud/logo.png",
"image": "https://auraajenticai.cloud/logo.png",
"description": "Aura Ajentic AI builds custom AI agents, automation pipelines, Web3 infrastructure, MT5 trading systems, data pipelines, and enterprise web apps — based in Dhaka, Bangladesh, remote-friendly.",
"email": "ceo@auraajenticai.cloud",
"telephone": "+8801911877091",
"foundingDate": "2026-07",
"areaServed": "Worldwide",
"address": {
"@type": "PostalAddress",
"addressLocality": "Dhaka",
"addressCountry": "BD"
},
"knowsAbout": ["AI agents", "automation", "Web3", "MT5 Expert Advisors", "SvelteKit", "Google Gemini", "Vertex AI", "n8n", "full-stack development"]
}
</script>
<!-- JSON-LD: Services -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ItemList",
"name": "Aura Ajentic AI Services",
"url": "https://auraajenticai.cloud/#/services",
"itemListElement": [
{
"@type": "ListItem", "position": 1,
"item": {
"@type": "Service",
"name": "Website & Webapp Development",
"description": "From landing pages to full SaaS dashboards — pixel-perfect, fast, and built to scale. SvelteKit, Next.js, React, Tailwind.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "Web Development", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/web-app-dev"
}
},
{
"@type": "ListItem", "position": 2,
"item": {
"@type": "Service",
"name": "AI Agent & Automation",
"description": "Custom AI agents that triage, decide, and execute — integrated with your tools via n8n, Google Vertex AI, and Gemini API.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "AI Development", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/ai-agent-automation"
}
},
{
"@type": "ListItem", "position": 3,
"item": {
"@type": "Service",
"name": "Web3 & Blockchain",
"description": "Wallets, smart contracts, multi-chain bridges, and on-chain audit trails. Gasless UX that hides complexity from end users.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "Blockchain Development", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/web3-blockchain"
}
},
{
"@type": "ListItem", "position": 4,
"item": {
"@type": "Service",
"name": "MT5 EA & Trading Automation",
"description": "Expert Advisors, real-time P&L dashboards, risk envelopes, and one-click kill switches for MetaTrader 5 platforms.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "Trading Automation", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/mt5-ea-trading"
}
},
{
"@type": "ListItem", "position": 5,
"item": {
"@type": "Service",
"name": "Browser Scraping & Data Pipeline",
"description": "Playwright/Puppeteer scrapers, proxy rotation, structured data extraction, and ETL pipelines into your DB or warehouse.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "Data Engineering", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/scraping-data-pipeline"
}
},
{
"@type": "ListItem", "position": 6,
"item": {
"@type": "Service",
"name": "Infrastructure & DevOps",
"description": "VPS setup, Docker, Coolify, Traefik, CI/CD pipelines, SSL, monitoring, and zero-downtime deploys on your own cloud.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "DevOps", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/infra-devops"
}
},
{
"@type": "ListItem", "position": 7,
"item": {
"@type": "Service",
"name": "AI-Powered Meta Ads",
"description": "AI agents connected directly to Meta's official API — optimizing bids, rotating creatives, and reallocating budgets every 15 minutes.",
"provider": { "@type": "Organization", "name": "Aura Ajentic AI" },
"serviceType": "Digital Advertising", "areaServed": "Worldwide",
"url": "https://auraajenticai.cloud/#/services/meta-ads-ai"
}
}
]
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -187,6 +326,10 @@
</style>
</head>
<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WMF863QM"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<div id="root"></div>
<!-- React 18 -->
@@ -194,16 +337,18 @@
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
<script type="text/babel" src="tweaks-panel.jsx"></script>
<script type="text/babel" src="src/icons.jsx"></script>
<script type="text/babel" src="src/data.jsx"></script>
<script type="text/babel" src="src/nav.jsx"></script>
<script type="text/babel" src="src/hero.jsx"></script>
<script type="text/babel" src="src/sections.jsx"></script>
<script type="text/babel" src="src/projects.jsx"></script>
<script type="text/babel" src="src/agent-showcase.jsx"></script>
<script type="text/babel" src="src/timeline-contact.jsx"></script>
<script type="text/babel" src="src/command-palette.jsx"></script>
<script type="text/babel" src="src/app.jsx"></script>
<script type="text/babel" src="tweaks-panel.jsx?v=9"></script>
<script type="text/babel" src="src/icons.jsx?v=9"></script>
<script type="text/babel" src="src/data.jsx?v=9"></script>
<script type="text/babel" src="src/nav.jsx?v=9"></script>
<script type="text/babel" src="src/hero.jsx?v=9"></script>
<script type="text/babel" src="src/sections.jsx?v=9"></script>
<script type="text/babel" src="src/projects.jsx?v=9"></script>
<script type="text/babel" src="src/agent-showcase.jsx?v=9"></script>
<script type="text/babel" src="src/timeline-contact.jsx?v=9"></script>
<script type="text/babel" src="src/command-palette.jsx?v=9"></script>
<script type="text/babel" src="src/chatbox.jsx?v=9"></script>
<script type="text/babel" src="src/pages.jsx?v=9"></script>
<script type="text/babel" src="src/app.jsx?v=9"></script>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://auraajenticai.cloud/sitemap.xml
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://auraajenticai.cloud/</loc>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>
+161 -45
View File
@@ -1,4 +1,4 @@
// Root app: theme + ⌘K + Tweaks + scroll reveal
// Root app: theme + ⌘K + Tweaks + hash router
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"accent": "#7c5cff",
@@ -8,6 +8,27 @@ const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"heroHeadlineSuffix": "automation engineer"
}/*EDITMODE-END*/;
// Simple hash router — reads window.location.hash
function useHashRoute() {
const [route, setRoute] = React.useState(() => {
const h = window.location.hash;
return h.startsWith('#/') ? h.slice(2) : '';
});
React.useEffect(() => {
const onHash = () => {
const h = window.location.hash;
const r = h.startsWith('#/') ? h.slice(2) : '';
setRoute(r);
window.scrollTo(0, 0);
};
window.addEventListener('hashchange', onHash);
return () => window.removeEventListener('hashchange', onHash);
}, []);
return route;
}
function App() {
const [theme, setTheme] = React.useState(() => {
return localStorage.getItem("aura-theme") || "dark";
@@ -15,11 +36,11 @@ function App() {
const [paletteOpen, setPaletteOpen] = React.useState(false);
const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
const [lang, setLang] = React.useState(() => localStorage.getItem("aura-lang") || "en");
const route = useHashRoute();
React.useEffect(() => { localStorage.setItem("aura-lang", lang); }, [lang]);
const toggleLang = () => setLang(l => l === "en" ? "bn" : "en");
// theme
React.useEffect(() => {
document.documentElement.dataset.theme = theme;
localStorage.setItem("aura-theme", theme);
@@ -33,7 +54,6 @@ function App() {
return () => window.removeEventListener("aura:toggle-theme", onToggle);
}, []);
// ⌘K
React.useEffect(() => {
const onKey = (e) => {
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
@@ -45,17 +65,83 @@ function App() {
return () => window.removeEventListener("keydown", onKey);
}, []);
// tweaks accent vars — apply to :root
React.useEffect(() => {
document.documentElement.style.setProperty("--accent", tweaks.accent);
document.documentElement.style.setProperty("--accent-2", tweaks.accent2);
document.documentElement.style.setProperty("--accent-glow", tweaks.accent + "59"); // ~35% alpha
document.documentElement.style.setProperty("--accent-glow", tweaks.accent + "59");
}, [tweaks.accent, tweaks.accent2]);
// density
const density = tweaks.density;
// Dynamic meta tags per route
React.useEffect(() => {
const BASE = 'Aura Ajentic AI';
const SERVICE_IDS = (PORTFOLIO_DATA.services || []).reduce((m, s) => {
m['services/' + s.id] = { title: `${s.name} — ${BASE}`, desc: s.description };
return m;
}, {});
const META = {
'': {
title: `${BASE} — AI Agents, Automation & Full-Stack Dev`,
desc: "Aura is an autonomous AI SaaS platform providing conversational AI sales agents, COD fraud defense, and Bangladesh's first Model Context Protocol (MCP) courier logistics engine for modern commerce brands.",
},
services: {
title: `Services — ${BASE}`,
desc: "AI agents, web development, Web3, MT5 trading automation, data pipelines, DevOps, and Meta Ads AI — 7 production-ready services that ship to production.",
},
stack: {
title: `Tech Stack — ${BASE}`,
desc: "What actually runs our own live products: React, SvelteKit, Next.js, Node.js, Supabase, Google Gemini · Vertex AI, n8n, Solidity, Docker, Coolify, and more.",
},
agents: {
title: `AI Agents — ${BASE}`,
desc: "Live demos of AI agents built with Google Gemini · Vertex AI, LangGraph, and n8n. Agents that triage, decide, and execute with tool access, memory, and audit trails.",
},
timeline: {
title: `Experience — ${BASE}`,
desc: "Founded July 2026. Real, dated milestones — from founding Aura Ajentic AI in Dhaka to our first paying client to Meta Tech Provider status. Not a résumé.",
},
contact: {
title: `Contact — ${BASE}`,
desc: "Get a quote for AI agents, automation, web development, Web3, or MT5 trading systems. Based in Dhaka, Bangladesh. Response within 24 hours.",
},
'case-studies': {
title: `Case Studies — ${BASE}`,
desc: "Explore our production metrics, customer growth, and live enterprise deployments powered by Aura Agentic AI.",
},
pricing: {
title: `Pricing — ${BASE}`,
desc: "Predictable B2B SaaS pricing for autonomous AI agents, Courier MCP logistics, and COD fraud defense. Starter, Growth, and Enterprise subscription plans.",
},
blog: {
title: `Blog — ${BASE}`,
desc: 'Real technical write-ups on AI agents, automation, and the infrastructure behind Aura Ajentic AI — published as we ship, not before.',
},
products: {
title: `Our Products — ${BASE}`,
desc: 'Snehalata and Glamours Touch — Aura\'s own live products, built and run on our own stack. Real businesses, not demos.',
},
privacy: {
title: `Privacy Policy — ${BASE}`,
desc: 'What Aura Ajentic AI collects, how it\'s used, and how to ask us to delete it.',
},
terms: {
title: `Terms of Service — ${BASE}`,
desc: 'Terms for Aura Ajentic AI project engagements and client dashboard access.',
},
...SERVICE_IDS,
};
// scroll reveal
const m = META[route] || META[''];
document.title = m.title;
const setMeta = (sel, val) => { const el = document.querySelector(sel); if (el) el.setAttribute('content', val); };
setMeta('meta[name="description"]', m.desc);
setMeta('meta[property="og:title"]', m.title);
setMeta('meta[property="og:description"]', m.desc);
setMeta('meta[property="og:url"]', `https://auraajenticai.cloud/${route ? '#/' + route : ''}`);
setMeta('meta[name="twitter:title"]', m.title);
setMeta('meta[name="twitter:description"]', m.desc);
}, [route]);
// scroll reveal (re-run on route change)
React.useEffect(() => {
const els = document.querySelectorAll(".reveal");
const io = new IntersectionObserver(entries => {
@@ -63,35 +149,77 @@ function App() {
}, { threshold: 0.1 });
els.forEach(el => io.observe(el));
return () => io.disconnect();
}, []);
}, [route]);
const density = tweaks.density;
const T = window;
const navProps = {
onCmdK: () => setPaletteOpen(true),
theme, onToggleTheme: toggleTheme,
lang, onToggleLang: toggleLang,
route,
};
const renderPage = () => {
// Service detail pages: #/services/:id
if (route.startsWith('services/')) {
const id = route.slice('services/'.length);
const svc = (PORTFOLIO_DATA.services || []).find(s => s.id === id);
if (svc) return <T.ServiceDetailPage svc={svc} lang={lang} />;
window.location.hash = '#/services';
return null;
}
switch (route) {
case 'services':
return <T.ServicesPage lang={lang} />;
case 'stack':
return <T.StackPage lang={lang} />;
case 'agents':
return <T.AgentsPage lang={lang} />;
case 'timeline':
return <T.TimelinePage lang={lang} />;
case 'contact':
return <T.ContactPage lang={lang} />;
case 'pricing':
return <T.PricingPage lang={lang} />;
case 'blog':
return <T.BlogPage lang={lang} />;
case 'case-studies':
return <T.CaseStudiesPage lang={lang} />;
case 'privacy':
return <T.PrivacyPage lang={lang} />;
case 'terms':
return <T.TermsPage lang={lang} />;
default:
return (
<main style={density === "compact" ? { fontSize: 14.5 } : undefined}>
<T.Hero headlinePrefix={tweaks.heroHeadlinePrefix} headlineSuffix={tweaks.heroHeadlineSuffix} lang={lang} />
<T.About lang={lang} />
<T.Skills lang={lang} />
<T.Projects lang={lang} />
<T.FlagshipProduct lang={lang} />
<T.AgentShowcase lang={lang} />
<T.Testimonials lang={lang} />
<T.Timeline lang={lang} />
<T.Contact lang={lang} />
</main>
);
}
};
return (
<>
<T.Nav onCmdK={() => setPaletteOpen(true)} theme={theme} onToggleTheme={toggleTheme} lang={lang} onToggleLang={toggleLang} />
<main style={density === "compact" ? { fontSize: 14.5 } : undefined}>
<T.Hero headlinePrefix={tweaks.heroHeadlinePrefix} headlineSuffix={tweaks.heroHeadlineSuffix} lang={lang} />
<T.About />
<T.Skills />
<T.Projects />
<T.AgentShowcase />
<T.Timeline />
<T.Contact lang={lang} />
</main>
<T.Footer />
<T.CommandPalette open={paletteOpen} onClose={() => setPaletteOpen(false)} />
<T.Nav {...navProps} />
{renderPage()}
<T.Footer lang={lang} />
<T.CommandPalette open={paletteOpen} onClose={() => setPaletteOpen(false)} lang={lang} />
<T.ChatboxWidget lang={lang} />
<window.TweaksPanel title="Tweaks">
<window.TweakSection label="Theme" />
<window.TweakRadio
label="Mode"
value={theme}
onChange={v => setTheme(v)}
options={["dark", "light"]}
/>
<window.TweakRadio label="Mode" value={theme} onChange={v => setTheme(v)} options={["dark", "light"]} />
<window.TweakSection label="Accent" />
<window.TweakColor label="Primary" value={tweaks.accent} onChange={v => setTweak("accent", v)} />
<window.TweakColor label="Secondary" value={tweaks.accent2} onChange={v => setTweak("accent2", v)} />
@@ -104,29 +232,17 @@ function App() {
["Mono", "#ffffff", "#a4a8b3"],
].map(([name, a, b]) => (
<button key={name} onClick={() => setTweak({ accent: a, accent2: b })} style={{
padding: "4px 8px",
fontSize: 10.5,
background: "transparent",
border: "1px solid rgba(0,0,0,.12)",
borderRadius: 5,
color: "#29261b",
display: "inline-flex", gap: 5, alignItems: "center",
cursor: "pointer",
padding: "4px 8px", fontSize: 10.5, background: "transparent",
border: "1px solid rgba(0,0,0,.12)", borderRadius: 5, color: "#29261b",
display: "inline-flex", gap: 5, alignItems: "center", cursor: "pointer",
}}>
<span style={{ width: 9, height: 9, background: a, borderRadius: "50%", display: "inline-block" }} />
{name}
</button>
))}
</div>
<window.TweakSection label="Density" />
<window.TweakRadio
label="Layout"
value={tweaks.density}
onChange={v => setTweak("density", v)}
options={["compact", "spacious"]}
/>
<window.TweakRadio label="Layout" value={tweaks.density} onChange={v => setTweak("density", v)} options={["compact", "spacious"]} />
<window.TweakSection label="Hero copy" />
<window.TweakText label="Prefix" value={tweaks.heroHeadlinePrefix} onChange={v => setTweak("heroHeadlinePrefix", v)} />
<window.TweakText label="Suffix" value={tweaks.heroHeadlineSuffix} onChange={v => setTweak("heroHeadlineSuffix", v)} />
+220
View File
@@ -0,0 +1,220 @@
// Aura Chatbox Widget
// Fetches config from dashboard API, routes messages through backend.
const DASHBOARD = 'https://aura.auraajenticai.cloud'
const ChatboxWidget = () => {
const [config, setConfig] = React.useState(null)
const [open, setOpen] = React.useState(false)
const [messages, setMessages] = React.useState([])
const [input, setInput] = React.useState('')
const [loading, setLoading] = React.useState(false)
const [isAfterHours, setIsAfterHours] = React.useState(false)
const messagesEndRef = React.useRef(null)
React.useEffect(() => {
fetch(`${DASHBOARD}/api/public/chatbox`)
.then(r => r.ok ? r.json() : null)
.then(cfg => {
if (!cfg) return
setConfig(cfg)
if (cfg.isEnabled) {
const afterHours = checkAfterHours(cfg.businessHours)
setIsAfterHours(afterHours)
setMessages([{ role: 'bot', text: cfg.welcomeMessage }])
}
})
.catch(() => {})
}, [])
React.useEffect(() => {
if (open && messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
}
}, [messages, open])
function checkAfterHours(businessHours) {
if (!businessHours) return false
const days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
const now = new Date()
const day = days[now.getDay()]
const hours = businessHours[day]
if (!hours || hours === 'closed') return true
const [open, close] = hours.split('-').map(t => {
const [h, m] = t.split(':').map(Number)
return h * 60 + (m || 0)
})
// UTC+6 Bangladesh time
const bdMin = ((now.getUTCHours() + 6) % 24) * 60 + now.getUTCMinutes()
return bdMin < open || bdMin >= close
}
async function sendMessage() {
if (!input.trim() || loading || isAfterHours) return
const text = input.trim()
setInput('')
setMessages(prev => [...prev, { role: 'user', text }])
setLoading(true)
try {
const res = await fetch(`${DASHBOARD}/api/public/chatbox/chat`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ message: text }),
})
const data = await res.json()
setMessages(prev => [...prev, { role: 'bot', text: data.reply || config?.fallbackMessage }])
} catch {
setMessages(prev => [...prev, { role: 'bot', text: config?.fallbackMessage || "I'll get back to you soon." }])
} finally {
setLoading(false)
}
}
function onKey(e) {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage() }
}
if (!config?.isEnabled) return null
return (
<div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 9000, display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 12 }}>
{/* Chat window */}
{open && (
<div style={{
width: 340, maxHeight: 480,
background: 'var(--bg-elev)',
border: '1px solid var(--line-strong)',
borderRadius: 16,
display: 'flex', flexDirection: 'column',
boxShadow: '0 20px 60px rgba(0,0,0,0.4)',
overflow: 'hidden',
}}>
{/* Header */}
<div style={{
padding: '14px 16px',
background: '#0a0a0a',
display: 'flex', alignItems: 'center', gap: 10,
borderBottom: '1px solid rgba(255,255,255,0.07)',
}}>
<div style={{
width: 32, height: 32, borderRadius: '50%',
background: 'linear-gradient(135deg, #c8a961 0%, #1d9e75 100%)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: 14, flexShrink: 0,
}}>⬡</div>
<div>
<div style={{ fontSize: 13, fontWeight: 600, color: '#f4f5f7' }}>Aura AI</div>
<div style={{ fontSize: 11, color: isAfterHours ? '#f59e0b' : '#4ade80', display: 'flex', alignItems: 'center', gap: 4 }}>
<span style={{ width: 6, height: 6, borderRadius: '50%', background: 'currentColor', display: 'inline-block' }} />
{isAfterHours ? 'After hours' : 'Online'}
</div>
</div>
<button onClick={() => setOpen(false)} style={{
marginLeft: 'auto', background: 'none', border: 'none',
color: '#6b7080', cursor: 'pointer', fontSize: 16, lineHeight: 1,
padding: '2px 4px',
}}>✕</button>
</div>
{/* Messages */}
<div style={{
flex: 1, overflowY: 'auto', padding: '12px 14px',
display: 'flex', flexDirection: 'column', gap: 8,
minHeight: 200, maxHeight: 280,
}}>
{messages.map((m, i) => (
<div key={i} style={{
display: 'flex',
justifyContent: m.role === 'user' ? 'flex-end' : 'flex-start',
}}>
<div style={{
maxWidth: '80%', padding: '8px 12px',
borderRadius: m.role === 'user' ? '12px 12px 2px 12px' : '12px 12px 12px 2px',
background: m.role === 'user' ? '#c8a961' : 'rgba(255,255,255,0.06)',
color: m.role === 'user' ? '#0a0a0a' : '#e0e2e8',
fontSize: 13, lineHeight: 1.5,
fontWeight: m.role === 'user' ? 500 : 400,
}}>{m.text}</div>
</div>
))}
{loading && (
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
<div style={{
padding: '8px 14px', borderRadius: '12px 12px 12px 2px',
background: 'rgba(255,255,255,0.06)', color: '#6b7080',
fontSize: 13, letterSpacing: 4,
}}>•••</div>
</div>
)}
{isAfterHours && (
<div style={{
padding: '8px 10px', background: 'rgba(245,158,11,0.1)',
border: '1px solid rgba(245,158,11,0.2)', borderRadius: 8,
fontSize: 12, color: '#f59e0b',
}}>
{config.afterHoursMessage}
</div>
)}
<div ref={messagesEndRef} />
</div>
{/* Input */}
<div style={{
padding: '10px 12px',
borderTop: '1px solid rgba(255,255,255,0.07)',
display: 'flex', gap: 8,
}}>
<input
value={input}
onChange={e => setInput(e.target.value)}
onKeyDown={onKey}
disabled={isAfterHours || loading}
placeholder={isAfterHours ? 'Chat unavailable right now' : 'Ask me anything…'}
style={{
flex: 1, padding: '8px 12px',
background: 'rgba(255,255,255,0.05)',
border: '1px solid rgba(255,255,255,0.1)',
borderRadius: 8, color: '#f4f5f7',
fontSize: 13,
outline: 'none',
}}
/>
<button
onClick={sendMessage}
disabled={!input.trim() || loading || isAfterHours}
style={{
width: 34, height: 34, flexShrink: 0,
background: input.trim() && !isAfterHours ? '#c8a961' : 'rgba(255,255,255,0.06)',
border: 'none', borderRadius: 8,
color: input.trim() && !isAfterHours ? '#0a0a0a' : '#6b7080',
cursor: input.trim() && !isAfterHours ? 'pointer' : 'not-allowed',
fontSize: 15, display: 'flex', alignItems: 'center', justifyContent: 'center',
transition: 'background 0.15s',
}}
>↑</button>
</div>
</div>
)}
{/* Toggle button */}
<button
onClick={() => setOpen(o => !o)}
title="Chat with Aura AI"
style={{
width: 52, height: 52, borderRadius: '50%',
background: open ? '#0a0a0a' : 'linear-gradient(135deg, #c8a961 0%, #1d9e75 100%)',
border: open ? '2px solid rgba(255,255,255,0.15)' : 'none',
color: open ? '#f4f5f7' : '#0a0a0a',
fontSize: 20, cursor: 'pointer',
display: 'flex', alignItems: 'center', justifyContent: 'center',
boxShadow: open ? '0 4px 20px rgba(0,0,0,0.4)' : '0 4px 20px rgba(200,169,97,0.4)',
transition: 'all 0.2s',
}}
>
{open ? '✕' : '⬡'}
</button>
</div>
)
}
window.ChatboxWidget = ChatboxWidget
+398 -80
View File
@@ -1,75 +1,58 @@
// Content for the portfolio
const PORTFOLIO_DATA = {
brand: {
name: "Aura Agentic AI",
name: "Aura Ajentic AI",
handle: "@aura",
title: "Agentic AI & Full-Stack Development",
titleBn: "এজেন্টিক এআই ও ফুল-স্ট্যাক ডেভেলপমেন্ট",
tagline: "We build AI agents, automation & enterprise systems that work 24/7.",
taglineBn: "আমরা AI এজেন্ট, অটোমেশন ও এন্টারপ্রাইজ সিস্টেম তৈরি করি যা ২৪/৭ কাজ করে।",
location: "Dhaka, Bangladesh · Remote",
yearsExp: 7,
email: "hello@auraajenticai.cloud",
founded: "Jul 2026",
email: "ceo@auraajenticai.cloud",
whatsapp: "8801911877091",
domain: "auraajenticai.cloud",
socials: {
github: "https://github.com",
linkedin: "https://linkedin.com",
github: "https://github.com/khondokartowsif171",
linkedin: "https://www.linkedin.com/in/amirul-islam-redwan-90114a3ab/",
twitter: "https://twitter.com",
},
},
// Every number below is real and checkable today -- never add a stat we can't stand behind if
// someone asks where it comes from.
metrics: [
{ label: "Years shipping", value: "7+" },
{ label: "Agents in production", value: "40+" },
{ label: "Enterprise clients", value: "12" },
{ label: "Uptime maintained", value: "99.98%" },
{ label: "Products we built & run ourselves", labelBn: "আমাদের নিজের বানানো ও চালানো প্রোডাক্ট", value: "2" },
{ label: "Products in our own live catalog", labelBn: "আমাদের নিজের catalog-এ প্রোডাক্ট", value: "560+" },
{ label: "Meta-approved WhatsApp bot", labelBn: "Meta-approved WhatsApp বট", value: "Live" },
{ label: "Self-hosted infrastructure", labelBn: "নিজস্ব হোস্টেড ইনফ্রাস্ট্রাকচার", value: "100%" },
],
about: {
pitch: "I build the systems that act on behalf of teams — agents that triage, route, decide, and execute. The work spans the full stack: model orchestration, eval harnesses, queue infrastructure, dashboards, on-chain settlement, and the tedious connective tissue that turns a clever demo into something a CFO will sign off on.",
pitch: "We're a new studio building the systems that act on behalf of teams — agents that triage, route, decide, and execute. Rather than pitch and disappear, we build our own products first and run them ourselves: a live WhatsApp sales bot answering real customers today, on infrastructure we host and pay for out of pocket, not resold AWS margins.",
pitchBn: "আমরা একটা নতুন স্টুডিও, যারা এমন সিস্টেম তৈরি করি যা টিমের হয়ে সরাসরি কাজ করে — এজেন্ট যা বিচার করে, route করে, সিদ্ধান্ত নেয়, এবং কাজ সম্পন্ন করে। শুধু পিচ দিয়ে হারিয়ে না গিয়ে, আমরা আগে নিজেদের প্রোডাক্ট বানাই ও নিজেরাই চালাই — একটা live WhatsApp sales বট যা আজই real কাস্টমারদের উত্তর দিচ্ছে, নিজেদের হোস্ট করা ইনফ্রাস্ট্রাকচারে, resold AWS margin না।",
bullets: [
"Designed agent runtimes for fintech & MLM platforms moving 8-figure GMV",
"Built orchestration layers across OpenAI, Anthropic, vLLM, and self-hosted models",
"Shipped Web3 settlement rails — wallets, signers, on-chain audit trails",
"Lead architect on three SaaS dashboards now serving 50k+ daily users",
"Built and run our own WhatsApp + Messenger sales bot, live in Bengali, 24/7",
"Self-host our entire stack on our own VPS with Coolify — no reselling AWS",
"Meta Tech Provider status — we can onboard other businesses' WhatsApp numbers",
"Enterprise Agentic Architecture, natively powered by Google Gemini & Vertex AI",
],
bulletsBn: [
"নিজেদের WhatsApp + Messenger sales বট বানিয়ে চালাচ্ছি, বাংলায়, ২৪/৭ live",
"পুরো স্ট্যাক নিজেদের VPS-এ Coolify দিয়ে self-host করি — AWS resell না",
"Meta Tech Provider status অর্জন করেছি — অন্য ব্যবসার WhatsApp নম্বরও onboard করতে পারি",
"গুগল জেমিনাই ও ভার্টেক্স এআই ইনফ্রাস্ট্রাকচারে পরিচালিত এন্টারপ্রাইজ এজেন্টিক সিস্টেম",
],
},
// Real tools we actually build with -- no fabricated proficiency percentages. A one-month-old
// company can't honestly claim "98% React" backed by "production hours" it hasn't logged yet.
stack: {
Frontend: [
{ name: "React", level: 98 },
{ name: "Next.js", level: 96 },
{ name: "TypeScript", level: 95 },
{ name: "Tailwind", level: 94 },
{ name: "Framer Motion", level: 88 },
],
Backend: [
{ name: "Node.js", level: 96 },
{ name: "Python · FastAPI", level: 92 },
{ name: "PostgreSQL", level: 94 },
{ name: "Supabase", level: 90 },
{ name: "Redis · BullMQ", level: 88 },
],
"AI / Agents": [
{ name: "LangGraph", level: 95 },
{ name: "OpenAI · Anthropic", level: 96 },
{ name: "Vector DBs", level: 90 },
{ name: "Eval harnesses", level: 86 },
{ name: "Tool routing", level: 92 },
],
"Web3": [
{ name: "Solidity", level: 84 },
{ name: "ethers · viem", level: 90 },
{ name: "Wallet integrations", level: 92 },
{ name: "On-chain indexing", level: 80 },
],
DevOps: [
{ name: "Docker", level: 92 },
{ name: "AWS · GCP", level: 88 },
{ name: "Vercel · Fly.io", level: 94 },
{ name: "GitHub Actions", level: 90 },
{ name: "Observability", level: 86 },
],
Frontend: ["React", "Next.js", "TypeScript", "Tailwind", "SvelteKit"],
Backend: ["Node.js", "PostgreSQL", "Supabase", "Drizzle ORM", "Hono"],
"AI / Agents": ["Google Gemini", "Vertex AI", "n8n", "LangGraph", "Meta MCP"],
"Web3": ["Solidity", "viem", "wagmi", "Cloudflare Workers"],
DevOps: ["Docker", "Coolify", "Traefik", "GitHub Actions", "Vercel"],
},
services: [
@@ -78,69 +61,318 @@ const PORTFOLIO_DATA = {
name: "Website & Webapp Development",
nameBn: "ওয়েবসাইট ও ওয়েবঅ্যাপ ডেভেলপমেন্ট",
kind: "Core Service",
kindBn: "কোর সার্ভিস",
description:
"From landing pages to full SaaS dashboards — pixel-perfect, fast, and built to scale. SvelteKit, Next.js, React, Tailwind.",
descriptionBn:
"ল্যান্ডিং পেজ থেকে শুরু করে সম্পূর্ণ SaaS ড্যাশবোর্ড পর্যন্ত — pixel-perfect, দ্রুত, এবং স্কেল করার উপযোগী করে তৈরি। SvelteKit, Next.js, React, Tailwind।",
stack: ["SvelteKit", "Next.js", "React", "Tailwind", "PostgreSQL"],
impact: { primary: "50k+", secondary: "daily users served" },
impact: { primary: "560+", secondary: "products in our own live store" },
color: "violet",
demo: "https://glamourstouch.com",
},
{
id: "ai-agent-automation",
name: "AI Agent & Automation",
nameBn: "এআই এজেন্ট ও অটোমেশন",
kind: "Core Service",
kindBn: "কোর সার্ভিস",
description:
"Custom AI agents that triage, decide, and execute — integrated with your tools via n8n, Anthropic, and OpenAI.",
stack: ["Anthropic Claude", "n8n", "LangGraph", "Node.js", "Hono"],
impact: { primary: "1.2M+", secondary: "agent runs / month" },
"Custom AI agents that triage, decide, and execute — integrated with your enterprise workflows via n8n, Vertex AI, and Google Gemini.",
descriptionBn:
"কাস্টম এআই এজেন্ট যা নিজে বিচার করে, সিদ্ধান্ত নেয় ও কাজ সম্পন্ন করে — n8n, Vertex AI ও Google Gemini-এর মাধ্যমে আপনার টুলসের সাথে যুক্ত।",
stack: ["Google Gemini", "Vertex AI", "n8n", "LangGraph", "Node.js", "Hono"],
impact: { primary: "24/7", secondary: "our own agent, answering real customers" },
color: "cyan",
demo: "https://demo-agenticai-website.vercel.app",
},
{
id: "web3-blockchain",
name: "Web3 & Blockchain",
nameBn: "ওয়েব৩ ও ব্লকচেইন",
kind: "Specialist Service",
kindBn: "স্পেশালিস্ট সার্ভিস",
description:
"Wallets, smart contracts, multi-chain bridges, and on-chain audit trails. Gasless UX that hides complexity from end users.",
descriptionBn:
"ওয়ালেট, স্মার্ট কন্ট্রাক্ট, মাল্টি-চেইন ব্রিজ, এবং অন-চেইন অডিট ট্রেইল। Gasless UX যা জটিলতা ইউজারের কাছ থেকে লুকিয়ে রাখে।",
stack: ["Solidity", "viem", "wagmi", "Cloudflare Workers"],
impact: { primary: "12 chains", secondary: "EVM + Solana" },
color: "green",
demo: "https://demo-cryptotradeanalysis-website.vercel.app",
},
{
id: "mt5-ea-trading",
name: "MT5 EA & Trading Automation",
nameBn: "MT5 EA ও ট্রেডিং অটোমেশন",
kind: "Specialist Service",
kindBn: "স্পেশালিস্ট সার্ভিস",
description:
"Expert Advisors, real-time P&L dashboards, risk envelopes, and one-click kill switches for MetaTrader 5 platforms.",
descriptionBn:
"Expert Advisor, রিয়েল-টাইম P&L ড্যাশবোর্ড, রিস্ক এনভেলপ, এবং MetaTrader 5 প্ল্যাটফর্মের জন্য এক-ক্লিক kill switch।",
stack: ["MQL5", "Go", "ClickHouse", "WebSockets", "React"],
impact: { primary: "<80ms", secondary: "tick-to-render latency" },
impact: { primary: "MQL5", secondary: "expert advisor development" },
color: "amber",
demo: "https://ea-dashboard-blush.vercel.app",
},
{
id: "scraping-data-pipeline",
name: "Browser Scraping & Data Pipeline",
nameBn: "ব্রাউজার স্ক্র্যাপিং ও ডেটা পাইপলাইন",
kind: "Specialist Service",
kindBn: "স্পেশালিস্ট সার্ভিস",
description:
"Playwright/Puppeteer scrapers, proxy rotation, structured data extraction, and ETL pipelines into your DB or warehouse.",
descriptionBn:
"Playwright/Puppeteer স্ক্র্যাপার, প্রক্সি রোটেশন, structured ডেটা এক্সট্র্যাকশন, এবং আপনার DB বা warehouse-এ ETL পাইপলাইন।",
stack: ["Playwright", "Puppeteer", "Python", "Airflow", "PostgreSQL"],
impact: { primary: "10M+", secondary: "records extracted / month" },
impact: { primary: "Playwright", secondary: "production-grade scraping" },
color: "violet",
demo: "https://portfolio-website-tan-six-24.vercel.app",
},
{
id: "infra-devops",
name: "Infrastructure & DevOps",
nameBn: "ইনফ্রাস্ট্রাকচার ও ডেভঅপস",
kind: "Specialist Service",
kindBn: "স্পেশালিস্ট সার্ভিস",
description:
"VPS setup, Docker, Coolify, Traefik, CI/CD pipelines, SSL, monitoring, and zero-downtime deploys on your own cloud.",
descriptionBn:
"VPS সেটআপ, Docker, Coolify, Traefik, CI/CD পাইপলাইন, SSL, মনিটরিং, এবং আপনার নিজের cloud-এ zero-downtime ডিপ্লয়।",
stack: ["Docker", "Coolify", "Traefik", "GitHub Actions", "PostgreSQL"],
impact: { primary: "99.98%", secondary: "uptime maintained" },
impact: { primary: "11+", secondary: "apps running on our own VPS" },
color: "cyan",
},
{
id: "meta-ads-ai",
name: "AI-Powered Meta Ads",
nameBn: "এআই-চালিত মেটা অ্যাডস",
kind: "Growth Service",
kindBn: "গ্রোথ সার্ভিস",
badge: "NEW · Meta MCP",
description:
"AI agents connected directly to Meta's official API — optimizing bids, rotating creatives, and reallocating budgets every 15 minutes. Not a human checking ads twice a day. A system that never sleeps.",
descriptionBn:
"Meta-এর official API-এর সাথে সরাসরি যুক্ত এআই এজেন্ট — প্রতি ১৫ মিনিটে bid অপ্টিমাইজ করে, creative পাল্টায়, বাজেট পুনর্বণ্টন করে। দিনে দুইবার মানুষ চেক করার মতো না — এমন একটা সিস্টেম যা কখনো ঘুমায় না।",
stack: ["Meta MCP", "Meta Ads API", "n8n", "Gemini AI", "Vertex AI"],
impact: { primary: "Official", secondary: "Meta MCP · direct API access" },
color: "rose",
highlights: [
"Real-time bid & budget optimization every 15 min",
"100+ ad variants A/B tested simultaneously by AI",
"Automated audience expansion & lookalike generation",
"Creative fatigue detection — pauses before burnout",
"Daily AI-written performance reports to your inbox",
"Full Meta API access via official MCP integration",
],
highlightsBn: [
"প্রতি ১৫ মিনিটে রিয়েল-টাইম bid ও বাজেট অপ্টিমাইজেশন",
"১০০+ অ্যাড ভ্যারিয়েন্ট একসাথে এআই দিয়ে A/B টেস্ট",
"স্বয়ংক্রিয় audience expansion ও lookalike generation",
"Creative fatigue detection — burnout হওয়ার আগেই থামায়",
"প্রতিদিন এআই-লিখিত পারফরম্যান্স রিপোর্ট আপনার ইনবক্সে",
"অফিসিয়াল MCP integration-এর মাধ্যমে সম্পূর্ণ Meta API অ্যাক্সেস",
],
},
{
id: "whatsapp-messenger-bot",
name: "WhatsApp & Messenger Sales Bot",
nameBn: "হোয়াটসঅ্যাপ ও মেসেঞ্জার সেলস বট",
kind: "Automation · Live",
kindBn: "অটোমেশন · লাইভ",
badge: "LIVE · Try it on WhatsApp",
description:
"A Bengali sales assistant that answers your customers 24/7 on WhatsApp and Messenger — with the real product photo, the real price, and the real discount pulled straight from your own database. It takes the order too. Running live on our own shop right now; message it and see.",
descriptionBn:
"একটা বাংলা সেলস অ্যাসিস্ট্যান্ট যা WhatsApp ও Messenger-এ আপনার কাস্টমারদের ২৪/৭ উত্তর দেয় — আসল প্রোডাক্ট ছবি, আসল দাম, আসল ছাড় সহ, সরাসরি আপনার নিজের ডেটাবেস থেকে। অর্ডারও নেয়। আমাদের নিজের দোকানে এখনই লাইভ চলছে; মেসেজ করে দেখুন।",
stack: ["WhatsApp Cloud API", "Meta Graph API", "Cloudflare Workers", "n8n", "Gemini", "Supabase"],
impact: { primary: "24/7", secondary: "replies in Bengali, in seconds" },
color: "emerald",
highlights: [
"Prices and photos come from your database — the AI never types a price, so it cannot quote a wrong one",
"Sends the actual product photo with every answer, not a link",
"Captures the full order — name, address, phone — straight into your system",
"Remembers the conversation, so \"ওইটা দেখান\" works",
"Flags suspicious COD orders and hands angry customers to a human",
],
highlightsBn: [
"দাম ও ছবি আসে আপনার ডেটাবেস থেকে — এআই কখনো নিজে দাম লেখে না, তাই ভুল দাম বলার সুযোগই নেই",
"প্রতিটা উত্তরে আসল প্রোডাক্ট ছবি পাঠায়, শুধু লিংক না",
"সম্পূর্ণ অর্ডার — নাম, ঠিকানা, ফোন — সরাসরি আপনার সিস্টেমে জমা করে",
"কথোপকথন মনে রাখে, তাই \"ওইটা দেখান\" বললেও বোঝে",
"সন্দেহজনক COD অর্ডার চিহ্নিত করে ও রাগান্বিত কাস্টমারকে মানুষের কাছে পাঠায়",
],
demo: "https://wa.me/8801712426871?text=Medicube%20er%20ki%20ki%20product%20ache%3F",
},
{
id: "social-autopilot",
name: "Social Media Autopilot",
nameBn: "সোশ্যাল মিডিয়া অটোপাইলট",
kind: "Automation · Live",
kindBn: "অটোমেশন · লাইভ",
badge: "LIVE · Running daily",
description:
"Your Facebook page posts itself. Daily product carousels and spotlights, pulled from your own catalog, captioned in Bengali and watermarked automatically — every day, without anyone opening a laptop. Running on our own page right now.",
descriptionBn:
"আপনার Facebook পেজ নিজে থেকেই পোস্ট করে। দৈনিক প্রোডাক্ট carousel ও spotlight, আপনার নিজের ক্যাটালগ থেকে নেওয়া, বাংলায় ক্যাপশন সহ ও স্বয়ংক্রিয়ভাবে watermark করা — প্রতিদিন, কারো ল্যাপটপ না খুলেই। আমাদের নিজের পেজে এখনই চলছে।",
stack: ["n8n", "Meta Graph API", "Supabase", "Sharp", "Gemini"],
impact: { primary: "0", secondary: "minutes of manual posting" },
color: "blue",
highlights: [
"Daily multi-product carousel — real photos, real prices from your catalog",
"Bengali captions written for you, watermarked with your brand",
"Every card deep-links to that product's page, not just the homepage",
"Rotates brands and products so the page never looks repetitive",
"Posts keep going out whether you're at the shop or asleep",
],
highlightsBn: [
"দৈনিক মাল্টি-প্রোডাক্ট carousel — আসল ছবি, আসল দাম, আপনার ক্যাটালগ থেকে",
"বাংলা ক্যাপশন আপনার জন্য লেখা, আপনার ব্র্যান্ড দিয়ে watermark করা",
"প্রতিটা কার্ড সরাসরি সেই প্রোডাক্টের পেজে নিয়ে যায়, শুধু হোমপেজ না",
"ব্র্যান্ড ও প্রোডাক্ট ঘুরিয়ে দেখায় যাতে পেজ কখনো একঘেয়ে না লাগে",
"আপনি দোকানে থাকুন বা ঘুমান, পোস্ট চলতেই থাকে",
],
},
{
id: "ecommerce-full",
name: "Complete Online Shop",
nameBn: "সম্পূর্ণ অনলাইন দোকান",
kind: "Bundle · End to end",
kindBn: "বান্ডল · এন্ড টু এন্ড",
badge: "EVERYTHING IN ONE",
description:
"The whole shop, one roof: the website, the WhatsApp sales bot, courier booking, daily social posts, and Meta ads — built, connected, and run together. This is exactly what we run for our own brand, so you are buying a system that already sells, not a plan.",
descriptionBn:
"পুরো দোকান, এক ছাদের নিচে: ওয়েবসাইট, WhatsApp সেলস বট, কুরিয়ার বুকিং, দৈনিক সোশ্যাল পোস্ট, এবং Meta অ্যাডস — সব তৈরি, সংযুক্ত ও একসাথে চালানো। এটাই আমরা নিজেদের ব্র্যান্ডের জন্য চালাই, তাই আপনি একটা পরিকল্পনা না, একটা already-বিক্রি-করা সিস্টেম কিনছেন।",
stack: ["React", "Supabase", "WhatsApp Cloud API", "n8n", "Meta Ads", "Steadfast"],
impact: { primary: "1", secondary: "team, running all of it" },
color: "violet",
highlights: [
"Storefront with real stock, discounts and cash on delivery",
"WhatsApp bot answering and taking orders 24/7 in Bengali",
"Orders flow into one dashboard — website and bot together",
"Courier booking and tracking without leaving the dashboard",
"Daily auto-posts and Meta ad campaigns driving the traffic",
"One team accountable for the whole chain, not five vendors",
],
highlightsBn: [
"আসল স্টক, ছাড় ও cash on delivery সহ স্টোরফ্রন্ট",
"WhatsApp বট ২৪/৭ বাংলায় উত্তর দেয় ও অর্ডার নেয়",
"অর্ডার এক ড্যাশবোর্ডে আসে — ওয়েবসাইট ও বট একসাথে",
"ড্যাশবোর্ড থেকে না বেরিয়েই কুরিয়ার বুকিং ও ট্র্যাকিং",
"দৈনিক অটো-পোস্ট ও Meta অ্যাড ক্যাম্পেইন ট্রাফিক আনে",
"পুরো চেইনের জন্য একটাই দায়বদ্ধ টিম, পাঁচটা vendor না",
],
},
{
id: "courier-mcp",
name: "Aura Courier MCP",
nameBn: "অরা কুরিয়ার MCP",
kind: "Connector · Live",
kindBn: "কানেক্টর · লাইভ",
badge: "LIVE · MCP Connector",
description:
"Universal Model Context Protocol (MCP) connector for every Bangladesh courier. Plug in your own courier keys, and book & track parcels — Steadfast, Pathao & RedX — straight from an AI conversation. Your shop's logistics, fully agentic.",
descriptionBn:
"বাংলাদেশের প্রতিটা কুরিয়ারের জন্য সর্বজনীন Model Context Protocol (MCP) কানেক্টর। নিজের কুরিয়ার key বসান, আর এআই কথোপকথন থেকেই পার্সেল বুক ও ট্র্যাক করুন — Steadfast, Pathao ও RedX। আপনার লজিস্টিক্স, ফুল্লি এজেন্টিক।",
stack: ["MCP Standard", "Steadfast", "Pathao", "RedX", "TypeScript"],
impact: { primary: "1", secondary: "connector · every courier" },
color: "amber",
highlights: [
"Book & track parcels from any AI agent — no dashboard hopping",
"One URL, your own courier keys — nothing stored by us",
"Steadfast & Pathao live · RedX & Paperfly coming",
"Works across Gemini, Antigravity, MCP clients, or hosted API",
"Open source — anyone can add it in seconds",
],
highlightsBn: [
"যেকোনো এআই এজেন্ট থেকে পার্সেল বুক ও ট্র্যাক — ড্যাশবোর্ড ঘোরাঘুরি লাগবে না",
"একটা URL, আপনার নিজের কুরিয়ার key — আমরা কিছুই সংরক্ষণ করি না",
"Steadfast ও Pathao লাইভ · RedX ও Paperfly আসছে",
"Gemini, Antigravity ও যেকোনো MCP ক্লায়েন্টে কাজ করে",
"ওপেন সোর্স — যে কেউ কয়েক সেকেন্ডে যোগ করতে পারে",
],
demo: "https://courier.auraajenticai.cloud",
repo: "https://github.com/auraajenticai/aura-courier-mcp",
},
],
// Empty on purpose -- the old array here was fabricated (invented names, companies and quotes
// that never existed). Never repopulate with placeholder content; only add a testimonial once a
// real client has actually given one. The Testimonials component renders an honest
// "new agency, real results coming soon" state when this is empty.
testimonials: [],
pricingTiers: [
{
name: "Starter",
badge: "Self-Serve",
price: 19,
period: "/month",
description: "Autonomous AI sales agent for growing online shops and brands.",
color: "violet",
features: [
"1 Autonomous AI Sales Agent (WhatsApp or Messenger)",
"1,000 Autonomous Conversations / month",
"Bengali & English Natural Language Processing (Benglish supported)",
"Aura Courier MCP Integration (Steadfast & Pathao)",
"Automated Consignment Tracking & Real-Time Status",
"Omnichannel Live Inbox with 1-Tap Human Handoff",
"Standard Email & Community Support",
],
cta: "Start 14-Day Free Trial",
href: "https://client.auraajenticai.cloud/#auth",
},
{
name: "Growth",
badge: "Most Popular",
price: 49,
period: "/month",
description: "Full omnichannel closing machine, COD fraud defense & multi-carrier MCP.",
color: "cyan",
features: [
"Omnichannel AI Agent (WhatsApp + Messenger + Instagram + Facebook Comments)",
"Unlimited Conversations & 24/7 Closing Engine",
"Automated COD Fraud Shield & Cancel Risk Prediction",
"Aura Courier MCP: Multi-Carrier Smart Routing (Steadfast, Pathao, RedX, Paperfly)",
"Google Maps Rooftop Geocoding & Zone/Delivery Fee Engine",
"28-Day Automated Customer Retention & Refill Machine",
"Full Client Dashboard, Live Analytics Studio & CSV Export",
"Priority WhatsApp & Live Chat Support",
],
cta: "Deploy Growth Plan",
href: "https://client.auraajenticai.cloud/#auth",
},
{
name: "Enterprise",
badge: "Custom Cloud",
price: null,
period: null,
description: "Dedicated enterprise infrastructure, custom LLM fine-tuning & ERP integration.",
color: "amber",
features: [
"Custom Fine-Tuned Domain LLMs (Retail, Healthcare, Hardware Repair)",
"Dedicated Isolated VPS / Private Cloud Infrastructure",
"Custom ERP, CRM & Warehouse Management System Webhooks",
"Multi-Tenant Bot Architecture for Agency & Franchise Networks",
"High-Throughput Dedicated Meta WABA & Cloud API Gateways",
"Dedicated Account Engineer & 99.9% Uptime SLA",
"24/7 Emergency Incident Escalation",
"Direct Engineer Access via WhatsApp & Slack",
],
cta: "Book Architecture Call",
href: "mailto:ceo@auraajenticai.cloud?subject=Enterprise SaaS Consultation",
},
],
// Empty on purpose -- the old array here was fabricated (fake publish dates predating Aura's own
// founding, an invented "18 months of production data" claim, and made-up client numbers matching
// the fake case studies). Never repopulate with placeholder posts; only publish once we've written
// something real. The blog page renders an honest "coming soon" state when this is empty.
blogArticles: [],
agentRun: [
{ t: 0, kind: "system", text: "agent.session :: id=run_8af3e2 model=claude-sonnet-4.5" },
{ t: 350, kind: "user", text: 'task: "Reconcile yesterday\'s payouts. Flag anything > $5k or > 3σ from the cohort baseline."' },
@@ -153,41 +385,127 @@ const PORTFOLIO_DATA = {
{ t: 5400, kind: "system", text: "session.end :: tokens=8,412 · cost=$0.083 · duration=5.4s" },
],
ownProducts: [
{
id: "snehalata",
name: "Snehalata",
tagline: "AI-Powered Clothing Ecosystem",
taglineBn: "এআই-চালিত ক্লথিং ইকোসিস্টেম",
description:
"Aura's own multi-vendor clothing marketplace for Bangladesh. Vendors register, list products, and sell — while Gemini AI handles style refinement, virtual try-on, fraud audits, and a 24/7 Bengali-language chat assistant. Built end-to-end on Aura's stack.",
descriptionBn:
"বাংলাদেশের জন্য Aura-র নিজস্ব multi-vendor ক্লথিং মার্কেটপ্লেস। Vendor-রা রেজিস্টার করে, প্রোডাক্ট লিস্ট করে, বিক্রি করে — আর Gemini AI স্টাইল রিফাইনমেন্ট, ভার্চুয়াল ট্রাই-অন, fraud audit, এবং ২৪/৭ বাংলা চ্যাট অ্যাসিস্ট্যান্ট সামলায়। সম্পূর্ণ Aura-র নিজের স্ট্যাকে তৈরি।",
url: "https://www.snehalata.com",
badge: "Ecosystem",
stack: ["SvelteKit", "Supabase", "Gemini AI", "Tailwind", "Vercel"],
features: [
"Multi-vendor marketplace with AI-powered vendor onboarding audit",
"Gemini-powered virtual try-on and style transfer for every product",
"24/7 Bengali AI chat assistant for shopping guidance",
"Bangladesh district-level vendor & product filtering",
"Full order lifecycle: placement → quality check → delivery tracking",
"CEO & vendor dashboards with real-time ecosystem stats",
],
featuresBn: [
"এআই-চালিত vendor onboarding audit সহ multi-vendor মার্কেটপ্লেস",
"প্রতিটা প্রোডাক্টের জন্য Gemini-চালিত ভার্চুয়াল ট্রাই-অন ও স্টাইল ট্রান্সফার",
"শপিং গাইডেন্সের জন্য ২৪/৭ বাংলা এআই চ্যাট অ্যাসিস্ট্যান্ট",
"বাংলাদেশ জেলা-ভিত্তিক vendor ও প্রোডাক্ট ফিল্টারিং",
"সম্পূর্ণ অর্ডার লাইফসাইকেল: অর্ডার → কোয়ালিটি চেক → ডেলিভারি ট্র্যাকিং",
"রিয়েল-টাইম ইকোসিস্টেম পরিসংখ্যান সহ CEO ও vendor ড্যাশবোর্ড",
],
color: "violet",
},
{
id: "glamourstouch",
name: "Glamours Touch",
tagline: "Beauty & Lifestyle E-Commerce",
taglineBn: "বিউটি ও লাইফস্টাইল ই-কমার্স",
description:
"Aura's own live e-commerce brand in the beauty & lifestyle space. We built it, we run it, we sell from it — end to end. Custom storefront, product catalog, cart, payment integration, and admin dashboard. Not a demo. A real business.",
descriptionBn:
"বিউটি ও লাইফস্টাইল সেক্টরে Aura-র নিজস্ব লাইভ ই-কমার্স ব্র্যান্ড। আমরাই বানিয়েছি, আমরাই চালাই, আমরাই বিক্রি করি — শুরু থেকে শেষ পর্যন্ত। কাস্টম স্টোরফ্রন্ট, প্রোডাক্ট ক্যাটালগ, কার্ট, পেমেন্ট ইন্টিগ্রেশন, এবং অ্যাডমিন ড্যাশবোর্ড। কোনো ডেমো না। একটা আসল ব্যবসা।",
url: "https://glamourstouch.com",
badge: "Live Product",
stack: ["React", "Vite", "Supabase", "Tailwind", "Vercel"],
features: [
"560+ product catalog with real stock and discount pricing",
"Cash on delivery across Bangladesh, order tracking built in",
"WhatsApp & Messenger sales bot answering customers 24/7 in Bengali",
"Mobile-first responsive storefront design",
"Admin dashboard for orders, products & analytics",
"Daily automated Facebook product posts — no manual posting",
],
featuresBn: [
"৫৬০+ প্রোডাক্ট ক্যাটালগ, আসল স্টক ও ছাড়ের দাম সহ",
"পুরো বাংলাদেশে cash on delivery, order tracking বিল্ট-ইন",
"WhatsApp ও Messenger সেলস বট ২৪/৭ বাংলায় কাস্টমারদের উত্তর দেয়",
"মোবাইল-ফার্স্ট রেসপনসিভ স্টোরফ্রন্ট ডিজাইন",
"অর্ডার, প্রোডাক্ট ও অ্যানালিটিক্সের জন্য অ্যাডমিন ড্যাশবোর্ড",
"দৈনিক স্বয়ংক্রিয় Facebook প্রোডাক্ট পোস্ট — ম্যানুয়াল পোস্টিং লাগে না",
],
color: "rose",
},
],
// Empty on purpose -- the old array here was fabricated (invented clients, quotes and metrics
// like "FinSync BD" and "AlphaEdge Capital" that never existed). Never repopulate with placeholder
// content; only add a case study once a real, verifiable project is done. The CaseStudiesPage
// component renders an honest "new agency, real results coming soon" state when this is empty.
caseStudies: [],
// Real Aura milestones, dated -- not an individual's job history. Add a new entry only when
// something actually, verifiably happened; never backfill a "years of experience" narrative.
experience: [
{
year: "2024 — Present",
role: "Founder & Principal Engineer",
company: "Aura Agentic Cloud",
kind: "Product",
detail: "Building the agent runtime layer — orchestration, evals, observability — used by 12 enterprise teams.",
year: "Sep 2026",
role: "Bangladesh's 1st Courier MCP Engine Launched",
roleBn: "বাংলাদেশের প্রথম কুরিয়ার MCP ইঞ্জিন চালু",
company: "Aura Logistics MCP",
kind: "Innovation",
kindBn: "উদ্ভাবন",
detail: "Launched Bangladesh's first Model Context Protocol (MCP) carrier orchestration hub integrating Steadfast, Pathao, RedX, Paperfly & Google Maps routing.",
detailBn: "Steadfast, Pathao, RedX, Paperfly ও Google Maps রাউটিং সমন্বয়ে দেশের প্রথম Model Context Protocol (MCP) লজিস্টিক হাব চালু।",
},
{
year: "2022 — 2024",
role: "Staff Full-Stack Engineer",
company: "Confidential · Fintech",
kind: "Contract",
detail: "Led the rebuild of an MLM compensation engine, ran the migration from monolith to multi-tenant.",
year: "Aug 2026",
role: "Meta Tech Provider status",
roleBn: "Meta Tech Provider status অর্জন",
company: "Aura Ajentic AI",
kind: "Milestone",
kindBn: "মাইলফলক",
detail: "Approved to onboard other businesses' WhatsApp Business numbers, on top of our own.",
detailBn: "নিজের ছাড়াও অন্য ব্যবসার WhatsApp Business নম্বর onboard করার অনুমোদন পেয়েছি।",
},
{
year: "2021 — 2022",
role: "Senior Engineer · Web3",
company: "Stealth DeFi protocol",
kind: "Contract",
detail: "Wallet UX, signer abstraction, on-chain settlement rails. Shipped before the protocol announced.",
year: "Aug 2026",
role: "WhatsApp Business API approved",
roleBn: "WhatsApp Business API অনুমোদিত",
company: "Aura Ajentic AI",
kind: "Milestone",
kindBn: "মাইলফলক",
detail: "Meta approved our WhatsApp messaging integration — our own sales bot went fully live.",
detailBn: "Meta আমাদের WhatsApp messaging integration অনুমোদন করেছে — আমাদের নিজের sales বট পুরোপুরি live হয়েছে।",
},
{
year: "2019 — 2021",
role: "Full-Stack Engineer",
company: "Series-B SaaS",
kind: "Full-time",
detail: "Owned the dashboard surface area — billing, RBAC, integrations. Pushed app from 4k to 28k DAU.",
year: "Jul 2026",
role: "First paying client signed",
roleBn: "প্রথম paying client",
company: "Applix BD",
kind: "Client",
kindBn: "ক্লায়েন্ট",
detail: "A Dhaka mobile-parts retailer became our first client — automated their Facebook posting and ad ops.",
detailBn: "ঢাকার একটা mobile-parts retailer আমাদের প্রথম client হন — তাদের Facebook posting আর ad কাজ automate করেছি।",
},
{
year: "2018 — 2019",
role: "Software Engineer",
company: "Agency · Remote",
kind: "Full-time",
detail: "Cut my teeth shipping React + Node products across e-commerce, logistics, and edtech.",
year: "Jul 2026",
role: "Aura Ajentic AI founded",
roleBn: "Aura Ajentic AI প্রতিষ্ঠা",
company: "Dhaka, Bangladesh",
kind: "Founding",
kindBn: "প্রতিষ্ঠা",
detail: "Started building our own live products first — Glamour's Touch (K-beauty e-commerce) and Snehalata (AI marketplace) — before pitching anyone else.",
detailBn: "আগে নিজেদের live প্রোডাক্ট বানানো শুরু করি — Glamour's Touch (K-beauty e-commerce) আর Snehalata (AI marketplace) — অন্য কাউকে pitch করার আগেই।",
},
],
};
+31 -20
View File
@@ -120,10 +120,30 @@ const TerminalRain = () => {
);
};
const HERO_TXT = {
en: {
pill: "Accepting new projects · Q3 2026",
getStarted: "Get Started Free",
viewServices: "View Services",
lastShipped: "Last shipped: 2 days ago",
},
bn: {
pill: "নতুন প্রজেক্ট নেওয়া হচ্ছে · Q3 2026",
getStarted: "ফ্রি শুরু করুন",
viewServices: "সার্ভিস দেখুন",
lastShipped: "সর্বশেষ শিপড: ২ দিন আগে",
},
};
// Same self-serve destination as the nav's "Get Started" -- lands a fresh signup straight on the
// client portal's service catalog instead of a blank dashboard.
const HERO_REGISTER_URL = "https://auth.auraajenticai.cloud/register?next=" + encodeURIComponent("https://client.auraajenticai.cloud/services");
const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
const D = PORTFOLIO_DATA;
const prefix = headlinePrefix || "Agentic AI &";
const suffix = headlineSuffix || "automation engineer";
const t = HERO_TXT[lang] || HERO_TXT.en;
return (
<section id="top" style={{
@@ -158,7 +178,7 @@ const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
boxShadow: "0 0 10px var(--good)",
animation: "pulse-dot 2s infinite",
}} />
Accepting new projects · Q3 2026
{t.pill}
</div>
{/* headline */}
@@ -189,39 +209,30 @@ const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
lineHeight: 1.55,
color: "var(--text-dim)",
}}>
{D.brand.tagline}
</p>
<p style={{
marginTop: 8,
maxWidth: 620,
fontSize: 14,
lineHeight: 1.6,
color: "var(--text-faint)",
fontFamily: "var(--font-sans)",
}}>
{D.brand.taglineBn}
{lang === "bn" ? D.brand.taglineBn : D.brand.tagline}
</p>
{/* CTAs */}
<div style={{ display: "flex", gap: 12, marginTop: 40, flexWrap: "wrap" }}>
<a href="#work" style={{
<a href={HERO_REGISTER_URL} style={{
display: "inline-flex",
alignItems: "center",
gap: 8,
padding: "12px 20px",
background: "var(--text)",
color: "var(--bg)",
background: "linear-gradient(110deg, var(--accent), var(--accent-2))",
color: "#fff",
fontSize: 14,
fontWeight: 500,
borderRadius: 10,
textDecoration: "none",
transition: "transform 0.15s",
}}
onMouseEnter={e => e.currentTarget.style.transform = "translateY(-1px)"}
onMouseLeave={e => e.currentTarget.style.transform = "none"}
>
View Services <Icons.Arrow size={14} />
{t.getStarted} <Icons.Arrow size={14} />
</a>
<a href="#contact" style={{
<a href="#work" style={{
display: "inline-flex",
alignItems: "center",
gap: 8,
@@ -234,7 +245,7 @@ const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
borderRadius: 10,
textDecoration: "none",
}}>
Get a Quote <Icons.ArrowUpRight size={14} />
{t.viewServices} <Icons.ArrowUpRight size={14} />
</a>
</div>
@@ -252,7 +263,7 @@ const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
<span>·</span>
<span>{D.brand.domain}</span>
<span>·</span>
<span>Last shipped: 2 days ago</span>
<span>{t.lastShipped}</span>
</div>
{/* metric strip */}
@@ -282,7 +293,7 @@ const Hero = ({ headlinePrefix, headlineSuffix, lang = "en" }) => {
fontFamily: "var(--font-mono)",
textTransform: "uppercase",
letterSpacing: "0.06em",
}}>{m.label}</div>
}}>{lang === "bn" ? m.labelBn : m.label}</div>
</div>
))}
</div>
+17 -11
View File
@@ -43,17 +43,23 @@ const Icons = {
Send: (p) => <Icon {...p}><path d="m22 2-7 20-4-9-9-4 20-7z" /></Icon>,
Globe: (p) => <Icon {...p}><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></Icon>,
Terminal: (p) => <Icon {...p}><path d="m4 17 6-6-6-6M12 19h8" /></Icon>,
Logo: ({ size = 28 }) => (
<svg width={size} height={size} viewBox="0 0 32 32" fill="none">
<defs>
<linearGradient id="logoG" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
<stop stopColor="var(--accent)" />
<stop offset="1" stopColor="var(--accent-2)" />
</linearGradient>
</defs>
<rect x="2" y="2" width="28" height="28" rx="8" fill="none" stroke="url(#logoG)" strokeWidth="1.5" />
<path d="M10 22 L16 8 L22 22 M12.5 17 H19.5" stroke="url(#logoG)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none" />
</svg>
WhatsApp: (p) => <Icon {...p}><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /></Icon>,
Logo: ({ size = 28, full = false }) => (
<img
src="logo.png"
width={full ? size * 4 : size}
height={size}
alt="Aura Ajentic AI"
style={{
objectFit: "contain",
objectPosition: "center",
borderRadius: full ? 0 : 4,
mixBlendMode: "screen",
display: "block",
flexShrink: 0,
}}
onError={e => { e.currentTarget.style.display = "none"; }}
/>
),
};
+79 -31
View File
@@ -1,7 +1,27 @@
// Top nav — minimal, sticky, blurred — mobile-responsive
const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
const NAV_LINKS = [
{ id: "services", label: "Services", labelBn: "সার্ভিস", url: "#/services" },
{ id: "case-studies", label: "Case Studies", labelBn: "কেস স্টাডি", url: "#/case-studies" },
{ id: "pricing", label: "Pricing", labelBn: "মূল্য", url: "#/pricing" },
{ id: "blog", label: "Blog", labelBn: "ব্লগ", url: "#/blog" },
{ id: "contact", label: "Contact", labelBn: "যোগাযোগ", url: "#/contact" },
]
const NAV_TXT = {
en: { search: "Search", getQuote: "Get a Quote", clientLogin: "Client Login", getStarted: "Get Started" },
bn: { search: "খুঁজুন", getQuote: "কোট নিন", clientLogin: "ক্লায়েন্ট লগইন", getStarted: "শুরু করুন" },
};
// Where a self-serve account should land right after signing up -- the client portal's own
// service catalog, not a blank dashboard. aura-auth's /register already reads and honors `next`.
const REGISTER_URL = "https://auth.auraajenticai.cloud/register?next=" + encodeURIComponent("https://client.auraajenticai.cloud/services");
const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang, route }) => {
const [scrolled, setScrolled] = React.useState(false);
const [menuOpen, setMenuOpen] = React.useState(false);
const links = NAV_LINKS;
const t = NAV_TXT[lang] || NAV_TXT.en;
const bn = lang === "bn";
React.useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 12);
@@ -9,14 +29,6 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
return () => window.removeEventListener("scroll", onScroll);
}, []);
const links = [
{ id: "work", label: "Services" },
{ id: "stack", label: "Stack" },
{ id: "agents", label: "Agents" },
{ id: "timeline", label: "Timeline" },
{ id: "contact", label: "Contact" },
];
return (
<>
<nav style={{
@@ -54,18 +66,26 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
{/* Center links — hidden on mobile */}
<div style={{ display: "flex", gap: 4, alignItems: "center" }} className="nav-links">
{links.map(l => (
<a key={l.id} href={"#" + l.id} style={{
fontSize: 13.5,
color: "var(--text-dim)",
padding: "6px 12px",
borderRadius: 8,
transition: "all 0.15s",
}}
onMouseEnter={e => { e.currentTarget.style.color = "var(--text)"; e.currentTarget.style.background = "var(--line)"; }}
onMouseLeave={e => { e.currentTarget.style.color = "var(--text-dim)"; e.currentTarget.style.background = "transparent"; }}
>{l.label}</a>
))}
{links.map(l => {
const isActive = route === l.id;
return (
<a key={l.id} href={l.url || `#/${l.id}`} style={{
fontSize: 13.5,
color: isActive ? "var(--text)" : "var(--text-dim)",
background: isActive ? "var(--line)" : "transparent",
padding: "6px 12px",
borderRadius: 8,
transition: "all 0.15s",
fontWeight: isActive ? 500 : 400,
}}
onMouseEnter={e => { e.currentTarget.style.color = "var(--text)"; e.currentTarget.style.background = "var(--line)"; }}
onMouseLeave={e => {
e.currentTarget.style.color = isActive ? "var(--text)" : "var(--text-dim)";
e.currentTarget.style.background = isActive ? "var(--line)" : "transparent";
}}
>{bn && l.labelBn ? l.labelBn : l.label}</a>
);
})}
</div>
{/* Right — desktop */}
@@ -82,7 +102,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
fontSize: 12.5,
}}>
<Icons.Search size={13} />
<span>Search</span>
<span>{t.search}</span>
<kbd style={{
fontFamily: "var(--font-mono)",
fontSize: 10.5,
@@ -118,7 +138,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
{lang === "en" ? "বাং" : "EN"}
</button>
<a href="mailto:hello@auraajenticai.cloud?subject=Project Quote" className="nav-quote-btn" style={{
<a href="mailto:ceo@auraajenticai.cloud?subject=Project Quote" className="nav-quote-btn" style={{
padding: "7px 13px",
background: "transparent",
border: "1px solid var(--line)",
@@ -129,10 +149,24 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
textDecoration: "none",
whiteSpace: "nowrap",
}}>
Get a Quote
{t.getQuote}
</a>
<a href="https://auth.auraajenticai.cloud/login" className="nav-login-btn" style={{
padding: "8px 12px",
background: "transparent",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--text-dim)",
fontSize: 13,
fontWeight: 500,
textDecoration: "none",
whiteSpace: "nowrap",
}}>
{t.clientLogin}
</a>
<a href={REGISTER_URL} className="nav-signup-btn" style={{
display: "flex",
alignItems: "center",
gap: 6,
@@ -145,7 +179,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
textDecoration: "none",
whiteSpace: "nowrap",
}}>
Client Login <Icons.Arrow size={13} />
{t.getStarted} <Icons.Arrow size={13} />
</a>
</div>
@@ -187,10 +221,10 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
.nav-search-btn { display: none !important; }
.nav-quote-btn { display: none !important; }
.nav-badge { display: none !important; }
.nav-lang-btn { display: none !important; }
}
@media (max-width: 480px) {
.nav-login-btn { display: none !important; }
.nav-signup-btn { display: none !important; }
.nav-hamburger { display: flex !important; }
}
`}</style>
@@ -216,7 +250,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
{links.map(l => (
<a
key={l.id}
href={"#" + l.id}
href={l.url || `#${l.id}`}
onClick={() => setMenuOpen(false)}
style={{
fontSize: 15,
@@ -226,7 +260,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
display: "block",
borderBottom: "1px solid var(--line)",
}}
>{l.label}</a>
>{bn && l.labelBn ? l.labelBn : l.label}</a>
))}
<div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
<button onClick={() => { onToggleTheme(); setMenuOpen(false); }} style={{
@@ -253,7 +287,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
{lang === "en" ? "বাংলা" : "English"}
</button>
<a
href="mailto:hello@auraajenticai.cloud?subject=Project Quote"
href="mailto:ceo@auraajenticai.cloud?subject=Project Quote"
onClick={() => setMenuOpen(false)}
style={{
padding: "8px 14px",
@@ -264,10 +298,24 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
fontSize: 13,
textDecoration: "none",
}}
>Get a Quote</a>
>{t.getQuote}</a>
<a
href="https://auth.auraajenticai.cloud/login"
onClick={() => setMenuOpen(false)}
style={{
padding: "8px 14px",
background: "transparent",
border: "1px solid var(--line)",
color: "var(--text-dim)",
fontSize: 13,
fontWeight: 500,
borderRadius: 8,
textDecoration: "none",
}}
>{t.clientLogin}</a>
<a
href={REGISTER_URL}
onClick={() => setMenuOpen(false)}
style={{
padding: "8px 14px",
background: "var(--text)",
@@ -277,7 +325,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
borderRadius: 8,
textDecoration: "none",
}}
>Client Login</a>
>{t.getStarted}</a>
</div>
</div>
)}
+1404
View File
File diff suppressed because it is too large Load Diff
+100 -37
View File
@@ -7,9 +7,16 @@ const colorMap = {
amber: { bg: "rgba(251, 191, 36, 0.08)", border: "rgba(251, 191, 36, 0.25)", text: "#fcd34d" },
};
const ProjectCard = ({ p }) => {
const PROJ_TXT = {
en: { liveUseCase: "Live Use Case", noRepo: "No repository linked", viewRepo: "View repository" },
bn: { liveUseCase: "লাইভ ব্যবহার দেখুন", noRepo: "রিপোজিটরি যুক্ত নেই", viewRepo: "রিপোজিটরি দেখুন" },
};
const ProjectCard = ({ p, lang = "en" }) => {
const tint = colorMap[p.color] || colorMap.violet;
const [hover, setHover] = React.useState(false);
const t = PROJ_TXT[lang] || PROJ_TXT.en;
const bn = lang === "bn";
return (
<article
@@ -64,7 +71,7 @@ const ProjectCard = ({ p }) => {
letterSpacing: "0.06em",
}}>
<span style={{ width: 6, height: 6, borderRadius: "50%", background: tint.text }} />
{p.kind}
{bn ? p.kindBn : p.kind}
</div>
<div style={{
position: "absolute",
@@ -76,7 +83,7 @@ const ProjectCard = ({ p }) => {
background: tint.bg,
border: `1px solid ${tint.border}`,
borderRadius: 4,
}}>{p.kind}</div>
}}>{bn ? p.kindBn : p.kind}</div>
</div>
<div style={{ padding: 24, position: "relative" }}>
@@ -85,15 +92,7 @@ const ProjectCard = ({ p }) => {
fontSize: 20,
fontWeight: 500,
letterSpacing: "-0.02em",
}}>{p.name}</h3>
{p.nameBn && (
<div style={{
marginTop: 4,
fontSize: 12,
color: "var(--text-faint)",
fontFamily: "var(--font-sans)",
}}>{p.nameBn}</div>
)}
}}>{bn && p.nameBn ? p.nameBn : p.name}</h3>
<p style={{
marginTop: 12,
@@ -101,7 +100,7 @@ const ProjectCard = ({ p }) => {
fontSize: 14,
lineHeight: 1.55,
color: "var(--text-dim)",
}}>{p.description}</p>
}}>{bn && p.descriptionBn ? p.descriptionBn : p.description}</p>
{/* Stack badges */}
<div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 20 }}>
@@ -144,24 +143,39 @@ const ProjectCard = ({ p }) => {
}}>{p.impact.secondary}</div>
</div>
<div style={{ display: "flex", gap: 6 }}>
<button style={{
width: 34, height: 34,
display: "grid", placeItems: "center",
background: "transparent",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--text-dim)",
}} title="GitHub"><Icons.Github size={14} /></button>
<button style={{
padding: "0 14px", height: 34,
display: "inline-flex", alignItems: "center", gap: 6,
background: "var(--text)",
color: "var(--bg)",
border: "none",
borderRadius: 8,
fontSize: 13,
fontWeight: 500,
}}>Demo <Icons.ArrowUpRight size={12} /></button>
{p.gitRepo ? (
<a href={p.gitRepo} target="_blank" rel="noopener noreferrer" style={{
width: 34, height: 34,
display: "grid", placeItems: "center",
background: "transparent",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--text-dim)",
textDecoration: "none",
}} title={t.viewRepo}><Icons.Github size={14} /></a>
) : (
<span style={{
width: 34, height: 34,
display: "grid", placeItems: "center",
border: "1px solid var(--line)",
borderRadius: 8,
color: "var(--line-strong)",
}} title={t.noRepo}><Icons.Github size={14} /></span>
)}
{p.demo && (
<a href={p.demo} target="_blank" rel="noopener noreferrer" style={{
padding: "0 14px", height: 34,
display: "inline-flex", alignItems: "center", gap: 6,
background: "var(--text)",
color: "var(--bg)",
border: "none",
borderRadius: 8,
fontSize: 13,
fontWeight: 500,
textDecoration: "none",
cursor: "pointer",
}}>{t.liveUseCase} <Icons.ArrowUpRight size={12} /></a>
)}
</div>
</div>
</div>
@@ -298,16 +312,65 @@ const ProjectVisual = ({ id, tint, hover }) => {
return null;
};
const Projects = () => {
// Merge Dashboard API data (demo/repo links) into local static data
// Public API returns: { id, name, demo, repo, position }
function mergeServices(local, apiData) {
const byId = {};
apiData.forEach(s => { byId[s.id] = s; });
return local.map(s => {
const api = byId[s.id];
if (!api) return s;
return {
...s,
demo: api.demo || s.demo || null,
gitRepo: api.repo || null,
};
});
}
const PROJECTS_NUM_WORDS_BN = ['শূন্য','এক','দুই','তিন','চার','পাঁচ','ছয়','সাত','আট','নয়'];
const Projects = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const [services, setServices] = React.useState(D.services);
const bn = lang === "bn";
React.useEffect(() => {
const CACHE_KEY = 'aura_svc_v3';
const CACHE_TTL = 5 * 60 * 1000;
const cached = sessionStorage.getItem(CACHE_KEY);
if (cached) {
try {
const { data, ts } = JSON.parse(cached);
if (Date.now() - ts < CACHE_TTL && data.length > 0) {
setServices(mergeServices(D.services, data));
return;
}
} catch {}
}
fetch('https://aura.auraajenticai.cloud/api/public/services', { signal: AbortSignal.timeout(3000) })
.then(r => r.ok ? r.json() : null)
.then(data => {
if (Array.isArray(data) && data.length > 0) {
sessionStorage.setItem(CACHE_KEY, JSON.stringify({ data, ts: Date.now() }));
setServices(mergeServices(D.services, data));
}
})
.catch(() => {});
}, []);
return (
<section id="work" style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow="What we build"
num="03 / 06"
title={<>Six services. One team. All <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>production-grade</span>.</>}
sub="From landing pages to AI agent runtimes — we take your idea from spec to live deployment."
eyebrow={bn ? "আমরা যা বানাই" : "What we build"}
num={`03 / 06`}
title={bn
? <>{PROJECTS_NUM_WORDS_BN[services.length] || services.length}টা সার্ভিস। একটাই টিম। সব <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>প্রোডাকশন-গ্রেড</span>।</>
: <>{['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine'][services.length] || services.length} service{services.length !== 1 ? 's' : ''}. One team. All <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>production-grade</span>.</>}
sub={bn
? "ল্যান্ডিং পেজ থেকে এআই এজেন্ট রানটাইম পর্যন্ত — আমরা আপনার আইডিয়া spec থেকে লাইভ ডিপ্লয়মেন্টে নিয়ে যাই।"
: "From landing pages to AI agent runtimes — we take your idea from spec to live deployment."}
/>
<div style={{
@@ -315,7 +378,7 @@ const Projects = () => {
gridTemplateColumns: "repeat(2, 1fr)",
gap: 16,
}} className="proj-grid">
{D.services.map(p => <ProjectCard key={p.id} p={p} />)}
{services.map(p => <ProjectCard key={p.id} p={p} lang={lang} />)}
</div>
<style>{`
+394 -49
View File
@@ -28,15 +28,48 @@ const SectionHeader = ({ eyebrow, title, sub, num }) => (
</div>
);
const About = () => {
const ABOUT_TXT = {
en: {
eyebrow: "About",
title: <>We build the systems that act — not the demos that <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>impress</span>.</>,
glance: "At a glance",
startConvo: "Start a conversation",
rows: [
["Discipline", "Agentic systems · Full-stack"],
["Stack range", "TS · Python · Solidity"],
["Working with", "Founders · CTOs · Platform leads"],
["Engagement", "Embedded · Lead architect"],
["Location", "Location"],
],
years: "shipping",
},
bn: {
eyebrow: "পরিচিতি",
title: <>আমরা এমন সিস্টেম বানাই যা কাজ করে — যে ডেমো শুধু <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>মুগ্ধ করে</span> তা না।</>,
glance: "এক নজরে",
startConvo: "কথোপকথন শুরু করুন",
rows: [
["ডিসিপ্লিন", "এজেন্টিক সিস্টেম · ফুল-স্ট্যাক"],
["স্ট্যাক রেঞ্জ", "TS · Python · Solidity"],
["কাজ করি", "ফাউন্ডার · CTO · প্ল্যাটফর্ম লিড"],
["এনগেজমেন্ট", "এমবেডেড · লিড আর্কিটেক্ট"],
["লোকেশন", "Location"],
],
years: "শিপিং",
},
};
const About = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const bn = lang === "bn";
const t = ABOUT_TXT[lang] || ABOUT_TXT.en;
return (
<section id="about" style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow="About"
eyebrow={t.eyebrow}
num="01 / 06"
title={<>I architect the systems that act — not the demos that <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>impress</span>.</>}
title={t.title}
/>
<div style={{
@@ -51,7 +84,7 @@ const About = () => {
lineHeight: 1.65,
color: "var(--text-dim)",
margin: 0,
}}>{D.about.pitch}</p>
}}>{bn ? D.about.pitchBn : D.about.pitch}</p>
<ul style={{
marginTop: 32,
@@ -60,7 +93,7 @@ const About = () => {
display: "grid",
gap: 14,
}}>
{D.about.bullets.map((b, i) => (
{(bn ? D.about.bulletsBn : D.about.bullets).map((b, i) => (
<li key={i} style={{
display: "flex",
gap: 14,
@@ -82,16 +115,23 @@ const About = () => {
{/* Side card: at a glance */}
<div className="panel" style={{ padding: 28 }}>
<div className="eyebrow" style={{ marginBottom: 20 }}>At a glance</div>
<div className="eyebrow" style={{ marginBottom: 20 }}>{t.glance}</div>
<div style={{ display: "grid", gap: 16 }}>
{[
{(bn ? [
["ডিসিপ্লিন", "এজেন্টিক সিস্টেম · ফুল-স্ট্যাক"],
["প্রতিষ্ঠিত", D.brand.founded],
["স্ট্যাক রেঞ্জ", "TS · Python · Solidity"],
["কাজ করি", "ফাউন্ডার · CTO · প্ল্যাটফর্ম লিড"],
["ইনফ্রা", "নিজস্ব VPS · Coolify"],
["লোকেশন", D.brand.location],
] : [
["Discipline", "Agentic systems · Full-stack"],
["Years", `${D.brand.yearsExp}+ shipping`],
["Founded", D.brand.founded],
["Stack range", "TS · Python · Solidity"],
["Working with", "Founders · CTOs · Platform leads"],
["Engagement", "Embedded · Lead architect"],
["Infra", "Own VPS · Coolify"],
["Location", D.brand.location],
].map(([k, v]) => (
]).map(([k, v]) => (
<div key={k} style={{
display: "grid",
gridTemplateColumns: "110px 1fr",
@@ -113,7 +153,7 @@ const About = () => {
fontSize: 13,
color: "var(--accent)",
}}>
Start a conversation <Icons.ArrowUpRight size={13} />
{t.startConvo} <Icons.ArrowUpRight size={13} />
</a>
</div>
</div>
@@ -128,8 +168,17 @@ const About = () => {
);
};
const Skills = () => {
const CAT_BN = {
"Frontend": "ফ্রন্টএন্ড",
"Backend": "ব্যাকএন্ড",
"AI / Agents": "এআই / এজেন্ট",
"Web3": "ওয়েব৩",
"DevOps": "ডেভঅপস",
};
const Skills = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const bn = lang === "bn";
const cats = Object.keys(D.stack);
const [active, setActive] = React.useState(cats[0]);
const items = D.stack[active];
@@ -146,10 +195,10 @@ const Skills = () => {
<section id="stack" style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow="Stack"
eyebrow={bn ? "স্ট্যাক" : "Stack"}
num="02 / 06"
title="Tools I reach for, weighted by reps."
sub="Numbers are honest signal — not a vanity bar. They reflect production hours, not tutorials watched."
title={bn ? "যেসব টুল দিয়ে আমরা বানাই।" : "The tools we build with."}
sub={bn ? "আমাদের নিজেদের live প্রোডাক্টে (GT, Snehalata, Aura Platform) সত্যিই ব্যবহৃত — কোনো fake স্কিল-বার না।" : "What actually runs our own live products (GT, Snehalata, Aura Platform) — no fabricated skill bars, just the real list."}
/>
{/* Category tabs */}
@@ -181,7 +230,7 @@ const Skills = () => {
fontWeight: 500,
transition: "all 0.15s",
}}>
<I size={13} /> {c}
<I size={13} /> {bn ? CAT_BN[c] || c : c}
</button>
);
})}
@@ -189,47 +238,119 @@ const Skills = () => {
{/* Items */}
<div style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
gap: 12,
display: "flex",
flexWrap: "wrap",
gap: 10,
}}>
{items.map((s, i) => (
<div key={s.name} className="panel" style={{
padding: "20px 22px",
{items.map((name, i) => (
<div key={name} className="panel" style={{
padding: "12px 18px",
fontSize: 14, fontWeight: 500,
animation: `float-up 0.5s ${i * 0.05}s both`,
}}>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 14 }}>
<span style={{ fontSize: 14.5, fontWeight: 500 }}>{s.name}</span>
<span style={{
fontFamily: "var(--font-mono)",
fontSize: 11,
color: "var(--text-faint)",
}}>{s.level}</span>
</div>
<div style={{
height: 3,
background: "var(--line)",
borderRadius: 2,
overflow: "hidden",
position: "relative",
}}>
<div style={{
width: `${s.level}%`,
height: "100%",
background: "linear-gradient(90deg, var(--accent), var(--accent-2))",
borderRadius: 2,
animation: `grow-w 0.9s ${0.1 + i * 0.04}s both cubic-bezier(0.2,0.8,0.2,1)`,
transformOrigin: "left",
}} />
</div>
{name}
</div>
))}
</div>
</div>
</section>
);
};
// ─── TESTIMONIALS ─────────────────────────────────────────────────────────────
const TESTIMONIAL_COLORS = {
cyan: { bg: "rgba(0,212,255,0.07)", border: "rgba(0,212,255,0.20)", text: "#67e8f9" },
amber: { bg: "rgba(251,191,36,0.08)", border: "rgba(251,191,36,0.22)", text: "#fde68a" },
rose: { bg: "rgba(244,63,94,0.08)", border: "rgba(244,63,94,0.22)", text: "#fda4af" },
green: { bg: "rgba(34,197,94,0.07)", border: "rgba(34,197,94,0.20)", text: "#86efac" },
violet: { bg: "rgba(124,92,255,0.08)", border: "rgba(124,92,255,0.22)", text: "#a78bfa" },
};
const Testimonials = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const bn = lang === "bn";
return (
<section style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow={bn ? "ক্লায়েন্ট ফলাফল" : "Client Results"}
num="05 / 06"
title={bn
? <>শিপ করার পর ক্লায়েন্টরা যা <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>বলে</span></>
: <>What clients say after we <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>ship</span></>}
sub={bn ? "আসল প্রজেক্ট। আসল মেট্রিক্স। কোনো stock-photo testimonial না।" : "Real projects. Real metrics. No stock-photo testimonials."}
/>
{D.testimonials.length === 0 ? (
<div className="panel" style={{
padding: "48px 32px",
textAlign: "center",
borderRadius: "var(--radius)",
}}>
<p style={{ margin: 0, fontSize: 16, color: "var(--text-dim)", lineHeight: 1.6 }}>
{bn
? "আমরা নতুন প্রডাক্ট শিপ করছি — কাস্টমার কেস স্টাডি ও ফলাফল শীঘ্রই আসছে।"
: "New customer deployments in progress — case studies and production metrics coming soon."}
</p>
</div>
) : (
<div style={{
display: "grid",
gridTemplateColumns: "repeat(2, 1fr)",
gap: 20,
}} className="testimonials-grid">
{D.testimonials.map((t, i) => {
const c = TESTIMONIAL_COLORS[t.color] || TESTIMONIAL_COLORS.cyan;
return (
<div
key={i}
className="reveal panel"
style={{
padding: "28px 32px",
border: `1px solid ${c.border}`,
background: c.bg,
borderRadius: "var(--radius)",
}}
>
<div style={{
fontSize: 32, lineHeight: 1, color: c.text,
marginBottom: 16, fontFamily: "var(--font-serif)",
}}>"</div>
<p style={{
margin: "0 0 24px", fontSize: 15.5,
lineHeight: 1.65, color: "var(--text)",
}}>{bn && t.textBn ? t.textBn : t.text}</p>
<div style={{ display: "flex", alignItems: "center", gap: 12 }}>
<div style={{
width: 40, height: 40, borderRadius: "50%",
background: c.bg, border: `1px solid ${c.border}`,
display: "grid", placeItems: "center",
fontSize: 12, fontWeight: 600, color: c.text,
fontFamily: "var(--font-mono)", flexShrink: 0,
}}>{t.avatar}</div>
<div>
<div style={{ fontSize: 14, fontWeight: 500 }}>{t.name}</div>
<div style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>
{t.role} · {t.company}
</div>
</div>
<div style={{ marginLeft: "auto" }}>
<span style={{
fontSize: 10.5, padding: "3px 9px", borderRadius: 999,
background: "var(--bg-elev)", border: "1px solid var(--line)",
color: "var(--text-faint)", fontFamily: "var(--font-mono)",
whiteSpace: "nowrap",
}}>{t.service}</span>
</div>
</div>
</div>
);
})}
</div>
)}
<style>{`
@keyframes grow-w {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
@media (max-width: 720px) {
.testimonials-grid { grid-template-columns: 1fr !important; }
}
`}</style>
</div>
@@ -237,6 +358,230 @@ const Skills = () => {
);
};
// ─── FLAGSHIP PRODUCTS ───────────────────────────────────────────────────────
const PRODUCT_COLORS = {
rose: { bg: "rgba(244,63,94,0.08)", border: "rgba(244,63,94,0.22)", text: "#fda4af" },
violet: { bg: "rgba(124,92,255,0.08)", border: "rgba(124,92,255,0.22)", text: "#a78bfa" },
cyan: { bg: "rgba(0,212,255,0.07)", border: "rgba(0,212,255,0.20)", text: "#67e8f9" },
green: { bg: "rgba(34,197,94,0.07)", border: "rgba(34,197,94,0.20)", text: "#86efac" },
amber: { bg: "rgba(251,191,36,0.08)", border: "rgba(251,191,36,0.22)", text: "#fde68a" },
};
const OwnProductCard = ({ product, lang = "en" }) => {
const bn = lang === "bn";
const c = PRODUCT_COLORS[product.color] || PRODUCT_COLORS.violet;
return (
<div className="reveal" style={{
borderRadius: "var(--radius)", border: `1px solid ${c.border}`,
background: "var(--bg-card)", overflow: "hidden",
display: "flex", flexDirection: "column",
}}>
{/* Card header */}
<div style={{
background: `linear-gradient(145deg, ${c.bg.replace('0.08', '0.13')} 0%, rgba(0,0,0,0) 100%)`,
padding: "36px 36px 28px", borderBottom: `1px solid ${c.border}`,
position: "relative", overflow: "hidden",
}}>
<div style={{
position: "absolute", top: -50, right: -50, width: 180, height: 180,
borderRadius: "50%", pointerEvents: "none",
background: `radial-gradient(circle, ${c.bg.replace('0.08', '0.18')} 0%, transparent 65%)`,
}} />
{/* Badges */}
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 20, position: "relative" }}>
<span style={{
display: "inline-flex", alignItems: "center", gap: 5,
background: "rgba(34,197,94,0.10)", border: "1px solid rgba(34,197,94,0.28)",
borderRadius: 999, padding: "3px 10px 3px 7px",
fontSize: 10, fontFamily: "var(--font-mono)", color: "#4ade80", fontWeight: 600,
}}>
<span style={{
width: 5, height: 5, borderRadius: "50%", background: "#22c55e",
boxShadow: "0 0 6px rgba(34,197,94,0.9)", display: "inline-block",
animation: "glamour-pulse 2s ease-in-out infinite",
}} />
{bn ? "লাইভ" : "LIVE"}
</span>
{product.badge && (
<span style={{
fontSize: 10, fontFamily: "var(--font-mono)", color: c.text,
padding: "3px 9px", borderRadius: 999,
background: c.bg, border: `1px solid ${c.border}`,
}}>{product.badge}</span>
)}
<span style={{
fontSize: 10, color: "var(--text-faint)", fontFamily: "var(--font-mono)",
padding: "3px 9px", borderRadius: 999,
background: "var(--bg-elev)", border: "1px solid var(--line)",
marginLeft: "auto",
}}>{bn ? "Aura-র তৈরি" : "Built by Aura"}</span>
</div>
{/* Brand name */}
<div style={{ position: "relative" }}>
<h3 style={{
margin: "0 0 6px",
fontSize: "clamp(22px, 2.5vw, 32px)",
fontWeight: 700, fontFamily: "var(--font-serif)", fontStyle: "italic",
letterSpacing: "-0.01em",
background: `linear-gradient(135deg, ${c.text} 0%, #fff 80%)`,
WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent",
backgroundClip: "text",
}}>{product.name}</h3>
<p style={{
margin: 0, fontSize: 11.5, color: "var(--text-faint)",
fontFamily: "var(--font-mono)", letterSpacing: "0.1em",
textTransform: "uppercase",
}}>{bn && product.taglineBn ? product.taglineBn : product.tagline}</p>
</div>
</div>
{/* Card body */}
<div style={{ padding: "28px 36px 32px", display: "flex", flexDirection: "column", gap: 20, flex: 1 }}>
<p style={{ margin: 0, fontSize: 14.5, lineHeight: 1.65, color: "var(--text-dim)" }}>
{bn && product.descriptionBn ? product.descriptionBn : product.description}
</p>
{/* Top 3 features */}
<div style={{ display: "grid", gap: 8 }}>
{(bn && product.featuresBn ? product.featuresBn : product.features).slice(0, 3).map((f, i) => (
<div key={i} style={{ display: "flex", gap: 10, fontSize: 13, color: "var(--text)" }}>
<span style={{ color: c.text, flexShrink: 0, fontSize: 11, marginTop: 2 }}>✓</span>
{f}
</div>
))}
{product.features.length > 3 && (
<div style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)", paddingLeft: 21 }}>
{bn ? `+${product.features.length - 3}টা আরও ক্ষমতা` : `+${product.features.length - 3} more capabilities`}
</div>
)}
</div>
{/* Stack */}
<div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
{product.stack.map(s => (
<span key={s} style={{
fontSize: 11, padding: "3px 9px", borderRadius: 5,
background: c.bg, border: `1px solid ${c.border}`,
color: c.text, fontFamily: "var(--font-mono)",
}}>{s}</span>
))}
</div>
{/* CTAs */}
<div style={{ display: "flex", gap: 10, marginTop: "auto", paddingTop: 4 }}>
<a
href={product.url} target="_blank" rel="noopener noreferrer"
style={{
display: "inline-flex", alignItems: "center", gap: 7,
padding: "10px 20px",
background: `linear-gradient(135deg, ${c.bg.replace('0.08','0.6')}, ${c.bg.replace('0.08','0.4')})`,
color: "#fff", borderRadius: 9, fontSize: 13, fontWeight: 600,
textDecoration: "none", border: `1px solid ${c.border}`,
transition: "opacity 0.15s",
}}
onMouseEnter={e => e.currentTarget.style.opacity = "0.82"}
onMouseLeave={e => e.currentTarget.style.opacity = "1"}
>
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
<polyline points="15,3 21,3 21,9"/><line x1="10" y1="14" x2="21" y2="3"/>
</svg>
{bn ? "দেখুন →" : "Visit →"}
</a>
<a href="#/services/web-app-dev" style={{
display: "inline-flex", alignItems: "center", gap: 7,
padding: "10px 16px",
background: "transparent", border: `1px solid ${c.border}`,
color: c.text, borderRadius: 9, fontSize: 13,
textDecoration: "none", transition: "background 0.15s",
}}
onMouseEnter={e => e.currentTarget.style.background = c.bg}
onMouseLeave={e => e.currentTarget.style.background = "transparent"}
>{bn ? "আমারটা বানান →" : "Build Mine →"}</a>
</div>
</div>
</div>
);
};
const FlagshipProduct = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const products = D.ownProducts || [];
if (!products.length) return null;
const bn = lang === "bn";
const rose = { bg: "rgba(244,63,94,0.08)", border: "rgba(244,63,94,0.22)", text: "#fda4af" };
const violet = { bg: "rgba(124,92,255,0.08)", border: "rgba(124,92,255,0.22)", text: "#a78bfa" };
return (
<section style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow={bn ? "আমাদের নিজস্ব প্রোডাক্ট" : "Our Own Products"}
num="03.5 / 06"
title={bn
? <>আমরা শুধু ক্লায়েন্টদের জন্য বানাই না — নিজেদের জন্যও <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>বানাই।</span></>
: <>We don't just build for clients — we build for <span style={{ fontFamily: "var(--font-serif)", fontStyle: "italic", fontWeight: 400 }}>ourselves.</span></>}
sub={bn
? "এগুলো Aura-র নিজস্ব লাইভ প্রোডাক্ট — আসল ব্যবসা যা আমরা বানিয়েছি, চালাই, বড় করছি। ঘুরে দেখুন। এটাই আমরা আপনার জন্য শিপ করি।"
: "These are Aura's own live products — real businesses we built, run, and grow. Visit them. That's exactly what we ship for you."}
/>
{/* Products grid */}
<div className="own-products-grid" style={{
display: "grid",
gridTemplateColumns: `repeat(${Math.min(products.length, 2)}, 1fr)`,
gap: 20,
}}>
{products.map(p => <OwnProductCard key={p.id} product={p} lang={lang} />)}
</div>
{/* Bottom nudge */}
<div className="reveal" style={{
marginTop: 20, padding: "22px 32px",
background: "var(--bg-card)", border: "1px solid var(--line)",
borderRadius: "var(--radius)",
display: "flex", alignItems: "center", justifyContent: "space-between",
flexWrap: "wrap", gap: 16,
}}>
<div>
<span style={{ fontSize: 15, fontWeight: 500, color: "var(--text)" }}>
{bn ? "Aura AI প্ল্যাটফর্ম দিয়ে আপনার সেলস অটোমেট করতে চান?" : "Ready to automate your e-commerce sales with Aura AI?"}
</span>
<span style={{
display: "block", fontSize: 13, color: "var(--text-faint)",
marginTop: 3, fontFamily: "var(--font-mono)",
}}>
{bn ? "অটোনোমাস এআই সেলস এজেন্ট · কুরিয়ার MCP লজিস্টিকস · COD ফ্রড শিল্ড — $১৯/মাস থেকে শুরু" : "Autonomous AI Sales Agents · Courier MCP Logistics · COD Fraud Shield — from $19/mo"}
</span>
</div>
<a href="#/pricing" style={{
padding: "11px 24px",
background: "var(--text)", color: "var(--bg)",
borderRadius: 9, fontSize: 13.5, fontWeight: 500,
textDecoration: "none", whiteSpace: "nowrap", flexShrink: 0,
}}>{bn ? "প্ল্যান দেখুন →" : "Explore Plans →"}</a>
</div>
</div>
<style>{`
@keyframes glamour-pulse {
0%, 100% { opacity: 1; box-shadow: 0 0 7px rgba(34,197,94,0.9); }
50% { opacity: 0.55; box-shadow: 0 0 2px rgba(34,197,94,0.3); }
}
@media (max-width: 860px) {
.own-products-grid { grid-template-columns: 1fr !important; }
}
`}</style>
</section>
);
};
window.About = About;
window.Skills = Skills;
window.SectionHeader = SectionHeader;
window.Testimonials = Testimonials;
window.FlagshipProduct = FlagshipProduct;
+43 -157
View File
@@ -1,14 +1,15 @@
// Timeline + Contact + Footer
const Timeline = () => {
const Timeline = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const bn = lang === "bn";
return (
<section id="timeline" style={{ padding: "120px 0", borderTop: "1px solid var(--line)" }}>
<div className="container">
<SectionHeader
eyebrow="Trajectory"
eyebrow={bn ? "যাত্রাপথ" : "Trajectory"}
num="05 / 06"
title="Seven years, one through-line: shipping systems that work in production."
title={bn ? "একটাই ধারা: প্রোডাকশনে কাজ করা স্বয়ংক্রিয় এআই সিস্টেম শিপ করা।" : "One through-line: shipping autonomous AI systems that work in production."}
/>
<div style={{ position: "relative", paddingLeft: 32 }}>
@@ -69,7 +70,7 @@ const Timeline = () => {
fontSize: 10.5,
color: "var(--text-dim)",
fontFamily: "var(--font-mono)",
}}>{e.kind}</span>
}}>{bn ? e.kindBn : e.kind}</span>
</div>
<div>
<h3 style={{
@@ -77,7 +78,7 @@ const Timeline = () => {
fontSize: 19,
fontWeight: 500,
letterSpacing: "-0.01em",
}}>{e.role}</h3>
}}>{bn ? e.roleBn : e.role}</h3>
<div style={{
marginTop: 4,
fontSize: 14,
@@ -90,7 +91,7 @@ const Timeline = () => {
lineHeight: 1.6,
color: "var(--text-dim)",
maxWidth: 600,
}}>{e.detail}</p>
}}>{bn ? e.detailBn : e.detail}</p>
</div>
</div>
</div>
@@ -141,15 +142,26 @@ const Contact = ({ lang = "en" }) => {
if (Object.keys(e).length) return;
setStatus("sending");
try {
await fetch("https://n8n.auraajenticai.cloud/webhook/contact", {
const resp = await fetch("https://formsubmit.co/ajax/khondokartowsif171@gmail.com", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(form),
headers: { "Content-Type": "application/json", "Accept": "application/json" },
body: JSON.stringify({
_subject: `New Aura Inquiry — ${form.service}`,
_captcha: "false",
_template: "table",
name: form.name,
email: form.email,
service: form.service,
budget: form.budget || "Not specified",
message: form.message,
}),
});
const data = await resp.json();
if (!data.success) throw new Error("failed");
setStatus("sent");
} catch {
setStatus("idle");
setErrors({ message: "Network error — please email us directly." });
setErrors({ message: "Network error — please email us directly at ceo@auraajenticai.cloud" });
}
};
@@ -326,6 +338,17 @@ const Contact = ({ lang = "en" }) => {
}}>
<Icons.Mail size={18} /> {D.brand.email}
</a>
<a href={`https://wa.me/${D.brand.whatsapp}`} target="_blank" rel="noopener noreferrer" style={{
fontSize: 15,
fontWeight: 500,
display: "inline-flex",
alignItems: "center",
gap: 10,
marginTop: 12,
color: "#25D366",
}}>
<Icons.WhatsApp size={16} /> +{D.brand.whatsapp.replace(/^(\d{3})(\d{4})(\d{6})$/, "$1 $2-$3")}
</a>
<div style={{ marginTop: 24, display: "flex", gap: 8 }}>
{[
{ i: Icons.Github, l: "GitHub", h: D.brand.socials.github },
@@ -347,7 +370,7 @@ const Contact = ({ lang = "en" }) => {
</div>
</div>
<ChatbotWidget />
</div>
</div>
<style>{`
@@ -360,152 +383,11 @@ const Contact = ({ lang = "en" }) => {
);
};
const ChatbotWidget = () => {
const [msgs, setMsgs] = React.useState([
{ role: "bot", text: "Ask me anything about the work — projects, stack choices, timelines." },
]);
const [input, setInput] = React.useState("");
const [thinking, setThinking] = React.useState(false);
const scrollRef = React.useRef(null);
const ChatbotWidget = () => null;
React.useEffect(() => {
if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}, [msgs, thinking]);
const reply = async (q) => {
setThinking(true);
try {
const text = await window.claude.complete(
`You are a concise portfolio assistant for Aura, a senior agentic AI & full-stack engineer with 7+ years experience. Domains: AI agents, Web3, MLM/EA dashboards, full-stack. Answer in 1-3 sentences, professional but friendly. Question: ${q}`
);
setMsgs(m => [...m, { role: "bot", text }]);
} catch (e) {
setMsgs(m => [...m, { role: "bot", text: "Aura's offline — drop a note via the form and I'll reply within 48h." }]);
}
setThinking(false);
};
const send = () => {
const q = input.trim();
if (!q) return;
setMsgs(m => [...m, { role: "user", text: q }]);
setInput("");
reply(q);
};
return (
<div className="panel" style={{ padding: 0, overflow: "hidden" }}>
<div style={{
padding: "16px 20px",
borderBottom: "1px solid var(--line)",
display: "flex",
alignItems: "center",
gap: 10,
}}>
<div style={{
width: 28, height: 28,
display: "grid", placeItems: "center",
borderRadius: 7,
background: "var(--accent-glow)",
color: "var(--accent)",
}}><Icons.Sparkles size={14} /></div>
<div>
<div style={{ fontSize: 13.5, fontWeight: 500 }}>Ask about my work</div>
<div style={{ fontSize: 11, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>powered by claude · live</div>
</div>
<span style={{
marginLeft: "auto",
fontSize: 10.5,
padding: "2px 8px",
background: "color-mix(in srgb, var(--good) 15%, transparent)",
color: "var(--good)",
border: "1px solid color-mix(in srgb, var(--good) 30%, transparent)",
borderRadius: 999,
fontFamily: "var(--font-mono)",
textTransform: "uppercase",
letterSpacing: "0.06em",
}}>online</span>
</div>
<div ref={scrollRef} style={{
padding: 16,
height: 200,
overflowY: "auto",
display: "flex",
flexDirection: "column",
gap: 10,
fontSize: 13,
}}>
{msgs.map((m, i) => (
<div key={i} style={{
alignSelf: m.role === "user" ? "flex-end" : "flex-start",
maxWidth: "85%",
padding: "8px 12px",
background: m.role === "user" ? "var(--accent)" : "var(--bg-elev)",
color: m.role === "user" ? "white" : "var(--text)",
border: m.role === "user" ? "none" : "1px solid var(--line)",
borderRadius: 12,
lineHeight: 1.5,
}}>{m.text}</div>
))}
{thinking && (
<div style={{
alignSelf: "flex-start",
padding: "8px 12px",
background: "var(--bg-elev)",
border: "1px solid var(--line)",
borderRadius: 12,
display: "flex", gap: 4, alignItems: "center",
}}>
{[0,1,2].map(i => (
<span key={i} style={{
width: 5, height: 5, borderRadius: "50%",
background: "var(--text-faint)",
animation: `pulse-dot 1.2s ${i * 0.15}s infinite`,
}} />
))}
</div>
)}
</div>
<form onSubmit={(e) => { e.preventDefault(); send(); }} style={{
display: "flex",
gap: 8,
padding: 12,
borderTop: "1px solid var(--line)",
background: "var(--bg-elev)",
}}>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Ask about a project, stack, or timeline…"
style={{
flex: 1,
background: "var(--bg-card)",
color: "var(--text)",
border: "1px solid var(--line)",
borderRadius: 8,
padding: "9px 12px",
fontSize: 13,
fontFamily: "inherit",
outline: "none",
}}
/>
<button type="submit" style={{
padding: "0 12px",
background: "var(--text)",
color: "var(--bg)",
border: "none",
borderRadius: 8,
fontSize: 12,
fontWeight: 500,
display: "flex", alignItems: "center", gap: 6,
}}><Icons.Send size={12} /></button>
</form>
</div>
);
};
const Footer = () => {
const Footer = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const bn = lang === "bn";
return (
<footer style={{
borderTop: "1px solid var(--line)",
@@ -522,8 +404,12 @@ const Footer = () => {
<Icons.Logo size={22} />
<span style={{ fontSize: 13, color: "var(--text-dim)" }}>{D.brand.name} · {D.brand.domain}</span>
</div>
<div style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>
© 2026 — Built with intent.
<div style={{ display: "flex", alignItems: "center", gap: 20 }}>
<a href="#/privacy" style={{ fontSize: 12.5, color: "var(--text-dim)" }}>{bn ? "প্রাইভেসি" : "Privacy"}</a>
<a href="#/terms" style={{ fontSize: 12.5, color: "var(--text-dim)" }}>{bn ? "শর্তাবলী" : "Terms"}</a>
<div style={{ fontSize: 12, color: "var(--text-faint)", fontFamily: "var(--font-mono)" }}>
{bn ? "© ২০২৬ — যত্ন করে তৈরি।" : "© 2026 — Built with intent."}
</div>
</div>
</div>
</footer>
+45
View File
@@ -0,0 +1,45 @@
{
"cleanUrls": false,
"trailingSlash": false,
"rewrites": [
{
"source": "/privacy",
"destination": "/privacy.html"
},
{
"source": "/privacy.html",
"destination": "/privacy.html"
},
{
"source": "/terms",
"destination": "/terms.html"
},
{
"source": "/terms.html",
"destination": "/terms.html"
},
{
"source": "/((?!privacy|terms).*)",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
}
]
}
]
}