Spaces:
Running
---
Browse files## **🧠 The Executive & Technical Specification Prompt for LibyaPay (Final Hybrid Version)**
**"To build a leading hybrid payment platform in Libya, combining visual elegance, technical power, and absolute security. The platform supports all digital and telecom-based payment methods, including online cloud wallets, SIM-based wallets, NFC, QR, and offline USSD/SMS transactions, to ensure universal accessibility."**
---
### **1. Vision and Core Philosophy**
**Vision:** To empower every individual and merchant in Libya with seamless, secure, and inclusive access to the digital economy, regardless of their internet connectivity quality.
**Core Philosophy:**
1. **Security First:** Every technical decision must pass through a security filter. There is no compromise on the protection of user funds and data.
2. **Offline-First:** Core functionalities (SIM Wallet) must work completely without an internet connection.
3. **User-Centric:** The design and experience must be intuitive and easy, with a focus on simplicity and clarity.
4. **Scalability by Design:** The infrastructure must support growth from 1,000 to 10 million users without fundamental changes.
5. **Full Compliance:** Strict adherence to local regulations (Central Bank of Libya) and Sharia compliance.
---
### **2. Design System**
**Objective:** To build a modern, attractive, and trustworthy visual identity inspired by "Libyana Al-Beidha" with a futuristic touch.
#### **2.1. Color Palette**
* **Primary Color:** Vibrant purple (inspired by Libyana).
* `Primary-50`: `#F3E5F5`
* `Primary-100`: `#E1BEE7`
* `Primary-500`: `#9C27B0` (Main color for buttons and interactive elements)
* `Primary-700`: `#7B1FA2`
* `Primary-900`: `#4A148C`
* **Primary Gradient:** Linear gradient from `Primary-500` to `Primary-700`.
* **Neutral Colors:**
* `Background`: `#FAFAFA` (Light) / `#121212` (Dark)
* `Surface`: `#FFFFFF` (Light) / `#1E1E1E` (Dark)
* `On-Surface`: `#1C1B1F` (Light) / `#E6E1E5` (Dark)
* **Semantic Colors:**
* `Success`: `#4CAF50`
* `Warning`: `#FF9800`
* `Error`: `#F44336`
* `Info`: `#2196F3`
#### **2.2. Typography**
* **Arabic:** **Cairo** (Weights: 300, 400, 600, 700).
* **English:** **Inter** (Weights: 300, 400, 600, 700).
* **Rules:** Use `sp` (Scalable Pixels) to ensure readability.
#### **2.3. Iconography & Imagery**
* **Icons:** Consistent line icons with a uniform stroke width and a modern, minimalist design.
* **Illustrations:** Soft, abstract illustrations with pastel colors to support the visual experience.
#### **2.4. Components & Interactions**
* **Buttons:** Rounded corners (8px) with a ripple effect on press.
* **Text Fields:** Bottom border only with floating labels.
* **Cards:** Light shadows and generous internal padding.
* **Animations:** Smooth transitions (300ms ease-out) between screens, and micro-interactions on element interaction.
---
### **3. Frontend (Mobile App) Technical Specifications**
* **Framework:** **Flutter 3.x**
* **Language:** **Dart**
* **Architecture:** **Clean Architecture** with **Riverpod** for state management.
* **Routing:** **GoRouter** for secure and declarative navigation.
* **Localization:** Full support for Arabic (RTL) and English (LTR) using the `intl` package.
#### **3.1. Key Modules**
1. **Authentication Module:**
* Welcome screen, Login with Phone/Email.
* OTP verification.
* PIN creation (6 digits) and confirmation.
* Biometric login (Face ID/Fingerprint).
2. **SIM Onboarding Module:**
* Dual-SIM detection.
* USSD probe to verify the carrier.
* Parse the incoming reply message and store an encrypted SIM profile.
3. **Wallet Module:**
* The Wallet Module integrates both cloud-based and SIM-based wallets into a unified interface, allowing instant switching or transferring between online and offline balances.
* The hybrid model ensures users can make payments even when disconnected from the internet using **SIM USSD commands**, which are parsed, signed, and verified securely within the app.
* Floating Action Button (FAB) for quick transfer between wallets.
4. **Payments Module:**
* **P2P:** Enter phone number, scan QR.
* **P2M:** Scan merchant QR, Pay via NFC.
* **Bill Payments:** Bill list, select bill, pay.
* **Top-up:** Select carrier, enter number, pay.
* **Virtual Cards:** Display cards, hide/show details, freeze card.
* **SIM/USSD Payments:** Execute payments via USSD menus and SIM commands directly from within the app (no manual dialing). Supports automatic session parsing, encrypted command construction, and real-time reconciliation when online.
5. **Offline Module:**
* **USSD/SMS Handler:** The USSD Handler acts as a bridge between the app and the SIM operator network, allowing encrypted transaction signing and automated session management without user intervention. It ensures all SIM Wallet activities are queued, signed, and later synced to the central system.
* **Sync Queue:** A local database (Isar/Hive) to store signed transactions and receipts in offline mode.
* **Sync Mechanism:** A background service to upload transactions when internet is available.
6. **AI Assistant Module:**
* Text-based chat interface and voice interface.
* Supports voice-activated transactions (e.g., “Send 20 dinars to Ali via USSD”) and provides smart fallback suggestions when the internet is unavailable.
* Display financial insights (Budget Analyzer) and alerts.
---
### **4. Backend Technical Specifications**
* **Framework:** **NestJS (Node.js)**
* **Language:** **TypeScript**
* **Architecture:** **Microservices**
* `API Gateway`: Unified entry point.
* `Auth Service`: Authentication and authorization (JWT).
* `User & KYC Service`: User management and identity verification.
* `Wallet Service`: Wallet and balance management.
* `Transaction Service`: Processing and logging all transactions.
* `Payment Gateway Service`: Integration with banks and telecom operators. Includes connectors for telecom-based payment flows (Libyana, Almadar, etc.) that can process and reconcile SIM/USSD transactions with the central ledger.
* `Notification Service`: Sending real-time notifications (Push, SMS, Email).
* `Fraud Engine Service`: AI-powered anti-fraud service.
* `Admin Service`: Backend for the Admin Dashboard.
* **Database:**
* **PostgreSQL 15+:** Primary database (ACID compliant).
* **Redis 7+:** For caching, user sessions, and queues.
* **API Design:**
* **RESTful API** with **OpenAPI 3.0 (Swagger)** documentation.
* Full support for `Idempotency-Key` on all POST requests.
* **Webhooks** for external system integration (secured with HMAC-SHA256).
#### **4.1. Critical Business Logic**
* **SIM Transaction Reconciliation:**
* Endpoint: `POST /api/v1/sim/sync`.
* Accepts an array of locally signed receipts.
* Compares them with data from operator webhooks.
* On match, update the ledger and change transaction status to "settled".
* On mismatch, send an alert to the Admin Dashboard for manual reconciliation.
* **Risk Engine:**
* Every transaction passes through the `Fraud Engine Service`.
* The engine collects features (amount, time, geo-location, device, user behavior).
* Uses an ML model (LightGBM) to predict fraud probability.
* Returns a decision: `{ "decision": "allow", "reason": null, "shap_values": [...] }`.
* `shap_values` are saved for decision explainability.
---
### **5. AI/ML Module**
* **Framework:** **Python 3.10+**
* **Libraries:** `scikit-learn`, `LightGBM`, `pandas`, `numpy`, `SHAP`.
* **Models:**
1. **Fraud Detection Model:**
* **Data:** Transaction history, user data, device data.
* **Training:** Trained periodically (weekly/monthly) on new data.
* **Deployment:** Packaged as a microservice and exposed via a REST API.
2. **Financial Assistant (RAG):**
* **Technology:** **Retrieval-Augmented Generation (RAG)**.
* **Components:**
* **Vector Database:** (e.g., Pinecone, Weaviate) to store regulatory docs and FAQs.
* **LLM:** (e.g., GPT-4 via API or open-source like Llama 3) to generate answers.
* **Function:** Answer user questions, provide saving tips, bill reminders.
---
### **6. Infrastructure & DevOps**
* **Cloud:** **AWS**
* **Containers:** **Docker**
* **Orchestration:** **Kubernetes (EKS)**
* **CI/CD:** **GitHub Actions** for automated build, test, and deployment.
* **Monitoring:**
* **Metrics:** **Prometheus** + **Grafana**
* **Logging:** **ELK Stack** (Elasticsearch, Logstash, Kibana)
* **Tracing:** **Jaeger**
* **Key Management:** **AWS KMS** or an HSM.
* **Hybrid Transaction Gateway:** Deployed to handle both IP-based (HTTPs) and telecom-based (USSD/SMS) transaction routing.
---
### **7. Admin Dashboard**
* **Framework:** **Next.js 14** with **TypeScript**
* **UI Library:** **Tailwind CSS** or **Ant Design**
* **Modules:**
* **Main Dashboard:** Live stats (user count, transaction volume, alerts).
* **User Management:** View users, KYC status, ability to suspend accounts.
* **Fraud Review:** View transactions flagged as "review," with SHAP reasoning.
* **Merchant Management:** Onboard merchants, manage their settings, view reports.
* **Reconciliation:** Interface for reconciling unmatched SIM transactions.
* **Reporting:** Generate financial and operational reports (PDF, Excel).
---
### **8. Final Deliverables Required**
1. **Code Repositories:**
* `libyapay-mobile-app` (Flutter)
* `libyapay-backend` (NestJS Microservices)
* `libyapay-ml-engine` (Python)
* `libyapay-admin-dashboard` (Next.js)
* `libyapay-infrastructure` (Terraform/Helm)
2. **Documentation:**
* API documentation (OpenAPI/Swagger).
* Developer Guide.
* Deployment Guide.
* Architecture Diagrams.
3. **Prototypes:
- README.md +8 -5
- components/feature-card.js +144 -0
- components/footer.js +251 -0
- components/header.js +216 -0
- index.html +220 -19
- script.js +182 -0
- style.css +142 -19
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: LibyaPay Platform 🚀
|
| 3 |
+
colorFrom: purple
|
| 4 |
+
colorTo: red
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class FeatureCard extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
const icon = this.getAttribute('icon') || 'star';
|
| 4 |
+
const title = this.getAttribute('title') || 'Feature Title';
|
| 5 |
+
const description = this.getAttribute('description') || 'Feature description goes here';
|
| 6 |
+
|
| 7 |
+
this.attachShadow({ mode: 'open' });
|
| 8 |
+
this.shadowRoot.innerHTML = `
|
| 9 |
+
<style>
|
| 10 |
+
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&family=Inter:wght@300;400;600;700&display=swap');
|
| 11 |
+
|
| 12 |
+
:host {
|
| 13 |
+
display: block;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
.feature-card {
|
| 17 |
+
background: white;
|
| 18 |
+
padding: 2rem;
|
| 19 |
+
border-radius: 16px;
|
| 20 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
| 21 |
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 22 |
+
cursor: pointer;
|
| 23 |
+
height: 100%;
|
| 24 |
+
display: flex;
|
| 25 |
+
flex-direction: column;
|
| 26 |
+
font-family: 'Inter', sans-serif;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.feature-card:hover {
|
| 30 |
+
transform: translateY(-8px);
|
| 31 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
.feature-icon {
|
| 35 |
+
width: 60px;
|
| 36 |
+
height: 60px;
|
| 37 |
+
background: linear-gradient(135deg, #F3E5F5, #E1BEE7);
|
| 38 |
+
border-radius: 16px;
|
| 39 |
+
display: flex;
|
| 40 |
+
align-items: center;
|
| 41 |
+
justify-content: center;
|
| 42 |
+
margin-bottom: 1.5rem;
|
| 43 |
+
transition: all 0.3s ease;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
.feature-icon svg {
|
| 47 |
+
color: #9C27B0;
|
| 48 |
+
width: 28px;
|
| 49 |
+
height: 28px;
|
| 50 |
+
stroke-width: 2;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.feature-card:hover .feature-icon {
|
| 54 |
+
background: linear-gradient(135deg, #9C27B0, #7B1FA2);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
.feature-card:hover .feature-icon svg {
|
| 58 |
+
color: white;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.feature-title {
|
| 62 |
+
font-size: 1.25rem;
|
| 63 |
+
font-weight: 600;
|
| 64 |
+
color: #1C1B1F;
|
| 65 |
+
margin-bottom: 0.75rem;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
.feature-description {
|
| 69 |
+
color: #616161;
|
| 70 |
+
line-height: 1.6;
|
| 71 |
+
flex-grow: 1;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
.feature-link {
|
| 75 |
+
display: inline-flex;
|
| 76 |
+
align-items: center;
|
| 77 |
+
gap: 0.5rem;
|
| 78 |
+
color: #9C27B0;
|
| 79 |
+
text-decoration: none;
|
| 80 |
+
font-weight: 500;
|
| 81 |
+
margin-top: 1rem;
|
| 82 |
+
transition: gap 0.2s ease;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
.feature-link:hover {
|
| 86 |
+
gap: 0.75rem;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.feature-link svg {
|
| 90 |
+
width: 16px;
|
| 91 |
+
height: 16px;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
@media (max-width: 640px) {
|
| 95 |
+
.feature-card {
|
| 96 |
+
padding: 1.5rem;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
.feature-icon {
|
| 100 |
+
width: 50px;
|
| 101 |
+
height: 50px;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
.feature-title {
|
| 105 |
+
font-size: 1.125rem;
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
</style>
|
| 109 |
+
|
| 110 |
+
<div class="feature-card">
|
| 111 |
+
<div class="feature-icon">
|
| 112 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
|
| 113 |
+
${this.getIconPath(icon)}
|
| 114 |
+
</svg>
|
| 115 |
+
</div>
|
| 116 |
+
<h3 class="feature-title">${title}</h3>
|
| 117 |
+
<p class="feature-description">${description}</p>
|
| 118 |
+
<a href="#" class="feature-link">
|
| 119 |
+
Learn more
|
| 120 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
| 121 |
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
| 122 |
+
<polyline points="12 5 19 12 12 19"></polyline>
|
| 123 |
+
</svg>
|
| 124 |
+
</a>
|
| 125 |
+
</div>
|
| 126 |
+
`;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
getIconPath(iconName) {
|
| 130 |
+
const icons = {
|
| 131 |
+
'wifi-off': '<path d="M1 1l22 22"></path><path d="M5 12.85a11 11 0 0 1 5.95-5.95"></path><path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path><line x1="12" y1="20" x2="12.01" y2="20"></line>',
|
| 132 |
+
'shield': '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>',
|
| 133 |
+
'smartphone': '<rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line>',
|
| 134 |
+
'star': '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>',
|
| 135 |
+
'credit-card': '<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line>',
|
| 136 |
+
'grid': '<rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect>',
|
| 137 |
+
'activity': '<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>',
|
| 138 |
+
'message-circle': '<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"></path>'
|
| 139 |
+
};
|
| 140 |
+
return icons[iconName] || icons['star'];
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
customElements.define('feature-card', FeatureCard);
|
|
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class AppFooter extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&family=Inter:wght@300;400;600;700&display=swap');
|
| 7 |
+
|
| 8 |
+
:host {
|
| 9 |
+
display: block;
|
| 10 |
+
font-family: 'Inter', sans-serif;
|
| 11 |
+
background: linear-gradient(135deg, #4A148C, #7B1FA2);
|
| 12 |
+
color: white;
|
| 13 |
+
margin-top: 0;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
footer {
|
| 17 |
+
padding: 4rem 1.5rem 2rem;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
.footer-content {
|
| 21 |
+
max-width: 1280px;
|
| 22 |
+
margin: 0 auto;
|
| 23 |
+
display: grid;
|
| 24 |
+
grid-template-columns: 2fr 1fr 1fr 1fr;
|
| 25 |
+
gap: 3rem;
|
| 26 |
+
margin-bottom: 3rem;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.footer-brand {
|
| 30 |
+
max-width: 350px;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
.footer-logo {
|
| 34 |
+
display: flex;
|
| 35 |
+
align-items: center;
|
| 36 |
+
gap: 0.75rem;
|
| 37 |
+
font-size: 1.5rem;
|
| 38 |
+
font-weight: 700;
|
| 39 |
+
margin-bottom: 1rem;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
.footer-logo-icon {
|
| 43 |
+
width: 40px;
|
| 44 |
+
height: 40px;
|
| 45 |
+
background: white;
|
| 46 |
+
border-radius: 12px;
|
| 47 |
+
display: flex;
|
| 48 |
+
align-items: center;
|
| 49 |
+
justify-content: center;
|
| 50 |
+
color: #9C27B0;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
.footer-description {
|
| 54 |
+
color: rgba(255, 255, 255, 0.9);
|
| 55 |
+
line-height: 1.6;
|
| 56 |
+
margin-bottom: 1.5rem;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
.social-links {
|
| 60 |
+
display: flex;
|
| 61 |
+
gap: 1rem;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
.social-link {
|
| 65 |
+
width: 40px;
|
| 66 |
+
height: 40px;
|
| 67 |
+
background: rgba(255, 255, 255, 0.1);
|
| 68 |
+
border-radius: 50%;
|
| 69 |
+
display: flex;
|
| 70 |
+
align-items: center;
|
| 71 |
+
justify-content: center;
|
| 72 |
+
color: white;
|
| 73 |
+
text-decoration: none;
|
| 74 |
+
transition: all 0.3s ease;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.social-link:hover {
|
| 78 |
+
background: white;
|
| 79 |
+
color: #9C27B0;
|
| 80 |
+
transform: scale(1.1);
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
.footer-section h3 {
|
| 84 |
+
font-size: 1.125rem;
|
| 85 |
+
font-weight: 600;
|
| 86 |
+
margin-bottom: 1rem;
|
| 87 |
+
color: white;
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
.footer-links {
|
| 91 |
+
list-style: none;
|
| 92 |
+
padding: 0;
|
| 93 |
+
margin: 0;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
.footer-links li {
|
| 97 |
+
margin-bottom: 0.75rem;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.footer-links a {
|
| 101 |
+
color: rgba(255, 255, 255, 0.8);
|
| 102 |
+
text-decoration: none;
|
| 103 |
+
transition: color 0.2s ease;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
.footer-links a:hover {
|
| 107 |
+
color: white;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
.footer-bottom {
|
| 111 |
+
max-width: 1280px;
|
| 112 |
+
margin: 0 auto;
|
| 113 |
+
padding-top: 2rem;
|
| 114 |
+
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
| 115 |
+
display: flex;
|
| 116 |
+
justify-content: space-between;
|
| 117 |
+
align-items: center;
|
| 118 |
+
flex-wrap: wrap;
|
| 119 |
+
gap: 1rem;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.footer-bottom p {
|
| 123 |
+
color: rgba(255, 255, 255, 0.8);
|
| 124 |
+
margin: 0;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.footer-legal {
|
| 128 |
+
display: flex;
|
| 129 |
+
gap: 2rem;
|
| 130 |
+
list-style: none;
|
| 131 |
+
padding: 0;
|
| 132 |
+
margin: 0;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
.footer-legal a {
|
| 136 |
+
color: rgba(255, 255, 255, 0.8);
|
| 137 |
+
text-decoration: none;
|
| 138 |
+
transition: color 0.2s ease;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
.footer-legal a:hover {
|
| 142 |
+
color: white;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
@media (max-width: 768px) {
|
| 146 |
+
.footer-content {
|
| 147 |
+
grid-template-columns: 1fr;
|
| 148 |
+
gap: 2rem;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.footer-brand {
|
| 152 |
+
max-width: 100%;
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
.footer-bottom {
|
| 156 |
+
flex-direction: column;
|
| 157 |
+
text-align: center;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
.footer-legal {
|
| 161 |
+
flex-direction: column;
|
| 162 |
+
gap: 1rem;
|
| 163 |
+
text-align: center;
|
| 164 |
+
}
|
| 165 |
+
}
|
| 166 |
+
</style>
|
| 167 |
+
|
| 168 |
+
<footer>
|
| 169 |
+
<div class="footer-content">
|
| 170 |
+
<div class="footer-brand">
|
| 171 |
+
<div class="footer-logo">
|
| 172 |
+
<div class="footer-logo-icon">
|
| 173 |
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
| 174 |
+
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
|
| 175 |
+
<line x1="1" y1="10" x2="23" y2="10"></line>
|
| 176 |
+
</svg>
|
| 177 |
+
</div>
|
| 178 |
+
LibyaPay
|
| 179 |
+
</div>
|
| 180 |
+
<p class="footer-description">
|
| 181 |
+
Empowering Libya with secure, fast, and inclusive digital payment solutions. Available online and offline for everyone.
|
| 182 |
+
</p>
|
| 183 |
+
<div class="social-links">
|
| 184 |
+
<a href="#" class="social-link">
|
| 185 |
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 186 |
+
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
|
| 187 |
+
</svg>
|
| 188 |
+
</a>
|
| 189 |
+
<a href="#" class="social-link">
|
| 190 |
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 191 |
+
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
| 192 |
+
</svg>
|
| 193 |
+
</a>
|
| 194 |
+
<a href="#" class="social-link">
|
| 195 |
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 196 |
+
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
| 197 |
+
</svg>
|
| 198 |
+
</a>
|
| 199 |
+
<a href="#" class="social-link">
|
| 200 |
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 201 |
+
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zM5.838 12a6.162 6.162 0 1112.324 0 6.162 6.162 0 01-12.324 0zM12 16a4 4 0 110-8 4 4 0 010 8zm4.965-10.405a1.44 1.44 0 112.881.001 1.44 1.44 0 01-2.881-.001z"/>
|
| 202 |
+
</svg>
|
| 203 |
+
</a>
|
| 204 |
+
</div>
|
| 205 |
+
</div>
|
| 206 |
+
|
| 207 |
+
<div class="footer-section">
|
| 208 |
+
<h3>Product</h3>
|
| 209 |
+
<ul class="footer-links">
|
| 210 |
+
<li><a href="#">Features</a></li>
|
| 211 |
+
<li><a href="#">Security</a></li>
|
| 212 |
+
<li><a href="#">Pricing</a></li>
|
| 213 |
+
<li><a href="#">API Docs</a></li>
|
| 214 |
+
</ul>
|
| 215 |
+
</div>
|
| 216 |
+
|
| 217 |
+
<div class="footer-section">
|
| 218 |
+
<h3>Company</h3>
|
| 219 |
+
<ul class="footer-links">
|
| 220 |
+
<li><a href="#">About Us</a></li>
|
| 221 |
+
<li><a href="#">Careers</a></li>
|
| 222 |
+
<li><a href="#">Blog</a></li>
|
| 223 |
+
<li><a href="#">Press</a></li>
|
| 224 |
+
</ul>
|
| 225 |
+
</div>
|
| 226 |
+
|
| 227 |
+
<div class="footer-section">
|
| 228 |
+
<h3>Support</h3>
|
| 229 |
+
<ul class="footer-links">
|
| 230 |
+
<li><a href="#">Help Center</a></li>
|
| 231 |
+
<li><a href="#">Contact Us</a></li>
|
| 232 |
+
<li><a href="#">FAQ</a></li>
|
| 233 |
+
<li><a href="#">Status</a></li>
|
| 234 |
+
</ul>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
|
| 238 |
+
<div class="footer-bottom">
|
| 239 |
+
<p>© 2024 LibyaPay. All rights reserved.</p>
|
| 240 |
+
<ul class="footer-legal">
|
| 241 |
+
<li><a href="#">Privacy Policy</a></li>
|
| 242 |
+
<li><a href="#">Terms of Service</a></li>
|
| 243 |
+
<li><a href="#">Compliance</a></li>
|
| 244 |
+
</ul>
|
| 245 |
+
</div>
|
| 246 |
+
</footer>
|
| 247 |
+
`;
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
customElements.define('app-footer', AppFooter);
|
|
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class AppHeader extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&family=Inter:wght@300;400;600;700&display=swap');
|
| 7 |
+
|
| 8 |
+
:host {
|
| 9 |
+
display: block;
|
| 10 |
+
font-family: 'Inter', sans-serif;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
header {
|
| 14 |
+
position: fixed;
|
| 15 |
+
top: 0;
|
| 16 |
+
left: 0;
|
| 17 |
+
right: 0;
|
| 18 |
+
z-index: 50;
|
| 19 |
+
background: rgba(255, 255, 255, 0.95);
|
| 20 |
+
backdrop-filter: blur(10px);
|
| 21 |
+
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
| 22 |
+
transition: all 0.3s ease;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.scrolled {
|
| 26 |
+
background: white;
|
| 27 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
nav {
|
| 31 |
+
max-width: 1280px;
|
| 32 |
+
margin: 0 auto;
|
| 33 |
+
padding: 1rem 1.5rem;
|
| 34 |
+
display: flex;
|
| 35 |
+
justify-content: space-between;
|
| 36 |
+
align-items: center;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
.logo {
|
| 40 |
+
display: flex;
|
| 41 |
+
align-items: center;
|
| 42 |
+
gap: 0.75rem;
|
| 43 |
+
font-size: 1.5rem;
|
| 44 |
+
font-weight: 700;
|
| 45 |
+
color: #9C27B0;
|
| 46 |
+
text-decoration: none;
|
| 47 |
+
transition: transform 0.2s ease;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
.logo:hover {
|
| 51 |
+
transform: scale(1.05);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
.logo-icon {
|
| 55 |
+
width: 40px;
|
| 56 |
+
height: 40px;
|
| 57 |
+
background: linear-gradient(135deg, #9C27B0, #7B1FA2);
|
| 58 |
+
border-radius: 12px;
|
| 59 |
+
display: flex;
|
| 60 |
+
align-items: center;
|
| 61 |
+
justify-content: center;
|
| 62 |
+
color: white;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
.nav-links {
|
| 66 |
+
display: flex;
|
| 67 |
+
gap: 2rem;
|
| 68 |
+
align-items: center;
|
| 69 |
+
list-style: none;
|
| 70 |
+
margin: 0;
|
| 71 |
+
padding: 0;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
.nav-link {
|
| 75 |
+
color: #424242;
|
| 76 |
+
text-decoration: none;
|
| 77 |
+
font-weight: 500;
|
| 78 |
+
transition: color 0.2s ease;
|
| 79 |
+
position: relative;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
.nav-link::after {
|
| 83 |
+
content: '';
|
| 84 |
+
position: absolute;
|
| 85 |
+
bottom: -4px;
|
| 86 |
+
left: 0;
|
| 87 |
+
width: 0;
|
| 88 |
+
height: 2px;
|
| 89 |
+
background: #9C27B0;
|
| 90 |
+
transition: width 0.3s ease;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.nav-link:hover::after {
|
| 94 |
+
width: 100%;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.nav-link:hover {
|
| 98 |
+
color: #9C27B0;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
.nav-cta {
|
| 102 |
+
background: linear-gradient(135deg, #9C27B0, #7B1FA2);
|
| 103 |
+
color: white;
|
| 104 |
+
padding: 0.75rem 1.5rem;
|
| 105 |
+
border-radius: 2rem;
|
| 106 |
+
text-decoration: none;
|
| 107 |
+
font-weight: 600;
|
| 108 |
+
transition: all 0.3s ease;
|
| 109 |
+
box-shadow: 0 4px 6px -1px rgba(156, 39, 176, 0.3);
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
.nav-cta:hover {
|
| 113 |
+
transform: translateY(-2px);
|
| 114 |
+
box-shadow: 0 10px 15px -3px rgba(156, 39, 176, 0.3);
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.mobile-menu-toggle {
|
| 118 |
+
display: none;
|
| 119 |
+
background: none;
|
| 120 |
+
border: none;
|
| 121 |
+
cursor: pointer;
|
| 122 |
+
padding: 0.5rem;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
@media (max-width: 768px) {
|
| 126 |
+
.nav-links {
|
| 127 |
+
position: fixed;
|
| 128 |
+
top: 0;
|
| 129 |
+
right: -100%;
|
| 130 |
+
width: 80%;
|
| 131 |
+
max-width: 300px;
|
| 132 |
+
height: 100vh;
|
| 133 |
+
background: white;
|
| 134 |
+
flex-direction: column;
|
| 135 |
+
padding: 5rem 2rem 2rem;
|
| 136 |
+
gap: 1.5rem;
|
| 137 |
+
box-shadow: -4px 0 6px -1px rgba(0, 0, 0, 0.1);
|
| 138 |
+
transition: right 0.3s ease;
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
.nav-links.active {
|
| 142 |
+
right: 0;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.mobile-menu-toggle {
|
| 146 |
+
display: block;
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
.nav-cta {
|
| 150 |
+
width: 100%;
|
| 151 |
+
text-align: center;
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
</style>
|
| 155 |
+
|
| 156 |
+
<header id="header">
|
| 157 |
+
<nav>
|
| 158 |
+
<a href="#" class="logo">
|
| 159 |
+
<div class="logo-icon">
|
| 160 |
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
| 161 |
+
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
|
| 162 |
+
<line x1="1" y1="10" x2="23" y2="10"></line>
|
| 163 |
+
</svg>
|
| 164 |
+
</div>
|
| 165 |
+
LibyaPay
|
| 166 |
+
</a>
|
| 167 |
+
|
| 168 |
+
<ul class="nav-links" id="navLinks">
|
| 169 |
+
<li><a href="#features" class="nav-link">Features</a></li>
|
| 170 |
+
<li><a href="#payments" class="nav-link">Payments</a></li>
|
| 171 |
+
<li><a href="#security" class="nav-link">Security</a></li>
|
| 172 |
+
<li><a href="#about" class="nav-link">About</a></li>
|
| 173 |
+
<li><a href="#contact" class="nav-link">Contact</a></li>
|
| 174 |
+
<li><a href="#" class="nav-cta">Get Started</a></li>
|
| 175 |
+
</ul>
|
| 176 |
+
|
| 177 |
+
<button class="mobile-menu-toggle" id="mobileMenuToggle">
|
| 178 |
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
| 179 |
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
| 180 |
+
<line x1="3" y1="6" x2="21" y2="6"></line>
|
| 181 |
+
<line x1="3" y1="18" x2="21" y2="18"></line>
|
| 182 |
+
</svg>
|
| 183 |
+
</button>
|
| 184 |
+
</nav>
|
| 185 |
+
</header>
|
| 186 |
+
`;
|
| 187 |
+
|
| 188 |
+
// Add scroll effect
|
| 189 |
+
window.addEventListener('scroll', () => {
|
| 190 |
+
const header = this.shadowRoot.getElementById('header');
|
| 191 |
+
if (window.scrollY > 50) {
|
| 192 |
+
header.classList.add('scrolled');
|
| 193 |
+
} else {
|
| 194 |
+
header.classList.remove('scrolled');
|
| 195 |
+
}
|
| 196 |
+
});
|
| 197 |
+
|
| 198 |
+
// Mobile menu toggle
|
| 199 |
+
const mobileMenuToggle = this.shadowRoot.getElementById('mobileMenuToggle');
|
| 200 |
+
const navLinks = this.shadowRoot.getElementById('navLinks');
|
| 201 |
+
|
| 202 |
+
mobileMenuToggle.addEventListener('click', () => {
|
| 203 |
+
navLinks.classList.toggle('active');
|
| 204 |
+
});
|
| 205 |
+
|
| 206 |
+
// Close mobile menu when clicking a link
|
| 207 |
+
const links = navLinks.querySelectorAll('.nav-link');
|
| 208 |
+
links.forEach(link => {
|
| 209 |
+
link.addEventListener('click', () => {
|
| 210 |
+
navLinks.classList.remove('active');
|
| 211 |
+
});
|
| 212 |
+
});
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
customElements.define('app-header', AppHeader);
|
|
@@ -1,19 +1,220 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>LibyaPay - Digital Payment Platform</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 11 |
+
<link rel="stylesheet" href="style.css">
|
| 12 |
+
<script>
|
| 13 |
+
tailwind.config = {
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
'libyana': {
|
| 18 |
+
50: '#F3E5F5',
|
| 19 |
+
100: '#E1BEE7',
|
| 20 |
+
200: '#CE93D8',
|
| 21 |
+
300: '#BA68C8',
|
| 22 |
+
400: '#AB47BC',
|
| 23 |
+
500: '#9C27B0',
|
| 24 |
+
600: '#8E24AA',
|
| 25 |
+
700: '#7B1FA2',
|
| 26 |
+
800: '#6A1B9A',
|
| 27 |
+
900: '#4A148C',
|
| 28 |
+
},
|
| 29 |
+
'neutral': {
|
| 30 |
+
50: '#FAFAFA',
|
| 31 |
+
100: '#F5F5F5',
|
| 32 |
+
200: '#EEEEEE',
|
| 33 |
+
300: '#E0E0E0',
|
| 34 |
+
400: '#BDBDBD',
|
| 35 |
+
500: '#9E9E9E',
|
| 36 |
+
600: '#757575',
|
| 37 |
+
700: '#616161',
|
| 38 |
+
800: '#424242',
|
| 39 |
+
900: '#212121',
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
fontFamily: {
|
| 43 |
+
'cairo': ['Cairo', 'sans-serif'],
|
| 44 |
+
'inter': ['Inter', 'sans-serif'],
|
| 45 |
+
},
|
| 46 |
+
animation: {
|
| 47 |
+
'fade-in': 'fadeIn 0.5s ease-out',
|
| 48 |
+
'slide-up': 'slideUp 0.5s ease-out',
|
| 49 |
+
'pulse-slow': 'pulse 3s infinite',
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
</script>
|
| 55 |
+
</head>
|
| 56 |
+
<body class="bg-neutral-50 font-inter text-neutral-900">
|
| 57 |
+
<app-header></app-header>
|
| 58 |
+
<main>
|
| 59 |
+
<!-- Hero Section -->
|
| 60 |
+
<section class="relative overflow-hidden bg-gradient-to-br from-libyana-500 to-libyana-700 text-white">
|
| 61 |
+
<div class="absolute inset-0 bg-black opacity-20"></div>
|
| 62 |
+
<div class="relative container mx-auto px-6 py-24 md:py-32">
|
| 63 |
+
<div class="grid md:grid-cols-2 gap-12 items-center">
|
| 64 |
+
<div class="space-y-6 animate-fade-in">
|
| 65 |
+
<h1 class="text-4xl md:text-6xl font-bold leading-tight">
|
| 66 |
+
LibyaPay - أليباي<br>
|
| 67 |
+
<span class="text-libyana-100">Digital Payments for Libya</span>
|
| 68 |
+
</h1>
|
| 69 |
+
<p class="text-xl text-libyana-100">
|
| 70 |
+
Secure, fast, and inclusive payment platform supporting online and offline transactions for everyone in Libya.
|
| 71 |
+
</p>
|
| 72 |
+
<div class="flex flex-wrap gap-4">
|
| 73 |
+
<button class="bg-white text-libyana-600 px-8 py-3 rounded-full font-semibold hover:bg-libyana-50 transition-all transform hover:scale-105 shadow-lg">
|
| 74 |
+
Get Started
|
| 75 |
+
</button>
|
| 76 |
+
<button class="border-2 border-white text-white px-8 py-3 rounded-full font-semibold hover:bg-white hover:text-libyana-600 transition-all">
|
| 77 |
+
Learn More
|
| 78 |
+
</button>
|
| 79 |
+
</div>
|
| 80 |
+
</div>
|
| 81 |
+
<div class="relative animate-slide-up">
|
| 82 |
+
<img src="http://static.photos/technology/640x360/123" alt="Mobile App" class="rounded-2xl shadow-2xl">
|
| 83 |
+
<div class="absolute -bottom-6 -left-6 bg-white text-neutral-900 p-4 rounded-xl shadow-xl">
|
| 84 |
+
<div class="flex items-center gap-3">
|
| 85 |
+
<div class="w-12 h-12 bg-libyana-100 rounded-full flex items-center justify-center">
|
| 86 |
+
<i data-feather="smartphone" class="text-libyana-600"></i>
|
| 87 |
+
</div>
|
| 88 |
+
<div>
|
| 89 |
+
<p class="font-semibold">2M+ Users</p>
|
| 90 |
+
<p class="text-sm text-neutral-600">Trusted Nationwide</p>
|
| 91 |
+
</div>
|
| 92 |
+
</div>
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
</div>
|
| 96 |
+
</div>
|
| 97 |
+
<div class="absolute bottom-0 left-0 right-0">
|
| 98 |
+
<svg viewBox="0 0 1440 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
| 99 |
+
<path d="M0 120L60 110C120 100 240 80 360 70C480 60 600 60 720 65C840 70 960 80 1080 85C1200 90 1320 90 1380 90L1440 90V120H0Z" fill="#FAFAFA"/>
|
| 100 |
+
</svg>
|
| 101 |
+
</div>
|
| 102 |
+
</section>
|
| 103 |
+
|
| 104 |
+
<!-- Features Section -->
|
| 105 |
+
<section class="py-20 bg-white">
|
| 106 |
+
<div class="container mx-auto px-6">
|
| 107 |
+
<div class="text-center mb-16">
|
| 108 |
+
<h2 class="text-4xl font-bold text-neutral-900 mb-4">Why Choose LibyaPay؟</h2>
|
| 109 |
+
<p class="text-xl text-neutral-600">Revolutionary features designed for Libya's unique needs</p>
|
| 110 |
+
</div>
|
| 111 |
+
<div class="grid md:grid-cols-3 gap-8">
|
| 112 |
+
<feature-card
|
| 113 |
+
icon="wifi-off"
|
| 114 |
+
title="Offline Payments"
|
| 115 |
+
description="Make payments even without internet using SIM-based USSD transactions"
|
| 116 |
+
></feature-card>
|
| 117 |
+
<feature-card
|
| 118 |
+
icon="shield"
|
| 119 |
+
title="Bank-Level Security"
|
| 120 |
+
description="Advanced encryption and fraud detection keep your money safe"
|
| 121 |
+
></feature-card>
|
| 122 |
+
<feature-card
|
| 123 |
+
icon="smartphone"
|
| 124 |
+
title="Multi-Platform Support"
|
| 125 |
+
description="Works on all devices with cloud and SIM wallet integration"
|
| 126 |
+
></feature-card>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
</section>
|
| 130 |
+
|
| 131 |
+
<!-- Payment Methods Section -->
|
| 132 |
+
<section class="py-20 bg-neutral-50">
|
| 133 |
+
<div class="container mx-auto px-6">
|
| 134 |
+
<div class="text-center mb-16">
|
| 135 |
+
<h2 class="text-4xl font-bold text-neutral-900 mb-4">Multiple Payment Methods</h2>
|
| 136 |
+
<p class="text-xl text-neutral-600">Choose the payment method that works for you</p>
|
| 137 |
+
</div>
|
| 138 |
+
<div class="grid md:grid-cols-4 gap-6">
|
| 139 |
+
<div class="bg-white p-6 rounded-xl shadow-md hover:shadow-xl transition-all hover:scale-105">
|
| 140 |
+
<div class="w-16 h-16 bg-libyana-100 rounded-full flex items-center justify-center mb-4">
|
| 141 |
+
<i data-feather="credit-card" class="text-libyana-600 text-2xl"></i>
|
| 142 |
+
</div>
|
| 143 |
+
<h3 class="font-semibold text-lg mb-2">Virtual Cards</h3>
|
| 144 |
+
<p class="text-neutral-600">Instant virtual cards for online shopping</p>
|
| 145 |
+
</div>
|
| 146 |
+
<div class="bg-white p-6 rounded-xl shadow-md hover:shadow-xl transition-all hover:scale-105">
|
| 147 |
+
<div class="w-16 h-16 bg-libyana-100 rounded-full flex items-center justify-center mb-4">
|
| 148 |
+
<i data-feather="grid" class="text-libyana-600 text-2xl"></i>
|
| 149 |
+
</div>
|
| 150 |
+
<h3 class="font-semibold text-lg mb-2">QR Payments</h3>
|
| 151 |
+
<p class="text-neutral-600">Scan and pay in seconds</p>
|
| 152 |
+
</div>
|
| 153 |
+
<div class="bg-white p-6 rounded-xl shadow-md hover:shadow-xl transition-all hover:scale-105">
|
| 154 |
+
<div class="w-16 h-16 bg-libyana-100 rounded-full flex items-center justify-center mb-4">
|
| 155 |
+
<i data-feather="activity" class="text-libyana-600 text-2xl"></i>
|
| 156 |
+
</div>
|
| 157 |
+
<h3 class="font-semibold text-lg mb-2">NFC Payments</h3>
|
| 158 |
+
<p class="text-neutral-600">Tap to pay at supported terminals</p>
|
| 159 |
+
</div>
|
| 160 |
+
<div class="bg-white p-6 rounded-xl shadow-md hover:shadow-xl transition-all hover:scale-105">
|
| 161 |
+
<div class="w-16 h-16 bg-libyana-100 rounded-full flex items-center justify-center mb-4">
|
| 162 |
+
<i data-feather="message-circle" class="text-libyana-600 text-2xl"></i>
|
| 163 |
+
</div>
|
| 164 |
+
<h3 class="font-semibold text-lg mb-2">USSD/SMS</h3>
|
| 165 |
+
<p class="text-neutral-600">Payments without internet connection</p>
|
| 166 |
+
</div>
|
| 167 |
+
</div>
|
| 168 |
+
</div>
|
| 169 |
+
</section>
|
| 170 |
+
|
| 171 |
+
<!-- Stats Section -->
|
| 172 |
+
<section class="py-20 bg-gradient-to-r from-libyana-600 to-libyana-700 text-white">
|
| 173 |
+
<div class="container mx-auto px-6">
|
| 174 |
+
<div class="grid md:grid-cols-4 gap-8 text-center">
|
| 175 |
+
<div>
|
| 176 |
+
<div class="text-4xl font-bold mb-2">2M+</div>
|
| 177 |
+
<div class="text-libyana-200">Active Users</div>
|
| 178 |
+
</div>
|
| 179 |
+
<div>
|
| 180 |
+
<div class="text-4xl font-bold mb-2">10K+</div>
|
| 181 |
+
<div class="text-libyana-200">Merchants</div>
|
| 182 |
+
</div>
|
| 183 |
+
<div>
|
| 184 |
+
<div class="text-4xl font-bold mb-2">$50M+</div>
|
| 185 |
+
<div class="text-libyana-200">Transactions</div>
|
| 186 |
+
</div>
|
| 187 |
+
<div>
|
| 188 |
+
<div class="text-4xl font-bold mb-2">99.9%</div>
|
| 189 |
+
<div class="text-libyana-200">Uptime</div>
|
| 190 |
+
</div>
|
| 191 |
+
</div>
|
| 192 |
+
</div>
|
| 193 |
+
</section>
|
| 194 |
+
|
| 195 |
+
<!-- CTA Section -->
|
| 196 |
+
<section class="py-20 bg-white">
|
| 197 |
+
<div class="container mx-auto px-6 text-center">
|
| 198 |
+
<h2 class="text-4xl font-bold text-neutral-900 mb-4">Ready to Get Started?</h2>
|
| 199 |
+
<p class="text-xl text-neutral-600 mb-8">Join millions of Libyans using digital payments</p>
|
| 200 |
+
<div class="flex justify-center gap-4">
|
| 201 |
+
<button class="bg-libyana-600 text-white px-8 py-3 rounded-full font-semibold hover:bg-libyana-700 transition-all transform hover:scale-105 shadow-lg">
|
| 202 |
+
Download App
|
| 203 |
+
</button>
|
| 204 |
+
<button class="border-2 border-libyana-600 text-libyana-600 px-8 py-3 rounded-full font-semibold hover:bg-libyana-600 hover:text-white transition-all">
|
| 205 |
+
Become Merchant
|
| 206 |
+
</button>
|
| 207 |
+
</div>
|
| 208 |
+
</div>
|
| 209 |
+
</section>
|
| 210 |
+
</main>
|
| 211 |
+
<app-footer></app-footer>
|
| 212 |
+
|
| 213 |
+
<script src="components/header.js"></script>
|
| 214 |
+
<script src="components/footer.js"></script>
|
| 215 |
+
<script src="components/feature-card.js"></script>
|
| 216 |
+
<script src="script.js"></script>
|
| 217 |
+
<script>feather.replace();</script>
|
| 218 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 219 |
+
</body>
|
| 220 |
+
</html>
|
|
@@ -0,0 +1,182 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Initialize app when DOM is loaded
|
| 2 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 3 |
+
// Initialize all tooltips
|
| 4 |
+
initializeTooltips();
|
| 5 |
+
|
| 6 |
+
// Smooth scrolling for anchor links
|
| 7 |
+
initializeSmoothScroll();
|
| 8 |
+
|
| 9 |
+
// Add ripple effect to buttons
|
| 10 |
+
addRippleEffect();
|
| 11 |
+
|
| 12 |
+
// Initialize animation observer
|
| 13 |
+
initializeAnimationObserver();
|
| 14 |
+
|
| 15 |
+
// Parallax effect for hero section
|
| 16 |
+
initializeParallax();
|
| 17 |
+
});
|
| 18 |
+
|
| 19 |
+
// Initialize tooltips
|
| 20 |
+
function initializeTooltips() {
|
| 21 |
+
const tooltipElements = document.querySelectorAll('[data-tooltip]');
|
| 22 |
+
tooltipElements.forEach(element => {
|
| 23 |
+
element.addEventListener('mouseenter', showTooltip);
|
| 24 |
+
element.addEventListener('mouseleave', hideTooltip);
|
| 25 |
+
});
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// Show tooltip
|
| 29 |
+
function showTooltip(e) {
|
| 30 |
+
const tooltip = document.createElement('div');
|
| 31 |
+
tooltip.className = 'absolute bg-neutral-800 text-white text-sm px-3 py-2 rounded-lg z-50 pointer-events-none';
|
| 32 |
+
tooltip.textContent = e.target.dataset.tooltip;
|
| 33 |
+
tooltip.style.bottom = '100%';
|
| 34 |
+
tooltip.style.left = '50%';
|
| 35 |
+
tooltip.style.transform = 'translateX(-50%) translateY(-8px)';
|
| 36 |
+
tooltip.style.whiteSpace = 'nowrap';
|
| 37 |
+
|
| 38 |
+
e.target.style.position = 'relative';
|
| 39 |
+
e.target.appendChild(tooltip);
|
| 40 |
+
|
| 41 |
+
// Add arrow
|
| 42 |
+
const arrow = document.createElement('div');
|
| 43 |
+
arrow.className = 'absolute w-2 h-2 bg-neutral-800 rotate-45';
|
| 44 |
+
arrow.style.bottom = '-4px';
|
| 45 |
+
arrow.style.left = '50%';
|
| 46 |
+
arrow.style.transform = 'translateX(-50%)';
|
| 47 |
+
tooltip.appendChild(arrow);
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
// Hide tooltip
|
| 51 |
+
function hideTooltip(e) {
|
| 52 |
+
const tooltip = e.target.querySelector('.absolute');
|
| 53 |
+
if (tooltip) {
|
| 54 |
+
tooltip.remove();
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
// Smooth scrolling
|
| 59 |
+
function initializeSmoothScroll() {
|
| 60 |
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
| 61 |
+
anchor.addEventListener('click', function(e) {
|
| 62 |
+
e.preventDefault();
|
| 63 |
+
const target = document.querySelector(this.getAttribute('href'));
|
| 64 |
+
if (target) {
|
| 65 |
+
target.scrollIntoView({
|
| 66 |
+
behavior: 'smooth',
|
| 67 |
+
block: 'start'
|
| 68 |
+
});
|
| 69 |
+
}
|
| 70 |
+
});
|
| 71 |
+
});
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
// Add ripple effect
|
| 75 |
+
function addRippleEffect() {
|
| 76 |
+
document.querySelectorAll('button, .ripple').forEach(element => {
|
| 77 |
+
element.addEventListener('click', function(e) {
|
| 78 |
+
const ripple = document.createElement('span');
|
| 79 |
+
const rect = this.getBoundingClientRect();
|
| 80 |
+
const size = Math.max(rect.width, rect.height);
|
| 81 |
+
const x = e.clientX - rect.left - size / 2;
|
| 82 |
+
const y = e.clientY - rect.top - size / 2;
|
| 83 |
+
|
| 84 |
+
ripple.style.width = ripple.style.height = size + 'px';
|
| 85 |
+
ripple.style.left = x + 'px';
|
| 86 |
+
ripple.style.top = y + 'px';
|
| 87 |
+
ripple.classList.add('ripple');
|
| 88 |
+
|
| 89 |
+
this.appendChild(ripple);
|
| 90 |
+
|
| 91 |
+
setTimeout(() => {
|
| 92 |
+
ripple.remove();
|
| 93 |
+
}, 600);
|
| 94 |
+
});
|
| 95 |
+
});
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
// Animation observer for scroll animations
|
| 99 |
+
function initializeAnimationObserver() {
|
| 100 |
+
const observerOptions = {
|
| 101 |
+
threshold: 0.1,
|
| 102 |
+
rootMargin: '0px 0px -50px 0px'
|
| 103 |
+
};
|
| 104 |
+
|
| 105 |
+
const observer = new IntersectionObserver((entries) => {
|
| 106 |
+
entries.forEach(entry => {
|
| 107 |
+
if (entry.isIntersecting) {
|
| 108 |
+
entry.target.classList.add('animate-fade-in');
|
| 109 |
+
observer.unobserve(entry.target);
|
| 110 |
+
}
|
| 111 |
+
});
|
| 112 |
+
}, observerOptions);
|
| 113 |
+
|
| 114 |
+
document.querySelectorAll('.card-hover, .feature-card').forEach(el => {
|
| 115 |
+
observer.observe(el);
|
| 116 |
+
});
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
// Parallax effect for hero section
|
| 120 |
+
function initializeParallax() {
|
| 121 |
+
window.addEventListener('scroll', () => {
|
| 122 |
+
const scrolled = window.pageYOffset;
|
| 123 |
+
const parallax = document.querySelector('.hero-parallax');
|
| 124 |
+
if (parallax) {
|
| 125 |
+
parallax.style.transform = `translateY(${scrolled * 0.5}px)`;
|
| 126 |
+
}
|
| 127 |
+
});
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
// Number counter animation
|
| 131 |
+
function animateCounter(element, target, duration = 2000) {
|
| 132 |
+
let start = 0;
|
| 133 |
+
const increment = target / (duration / 16);
|
| 134 |
+
|
| 135 |
+
const timer = setInterval(() => {
|
| 136 |
+
start += increment;
|
| 137 |
+
if (start >= target) {
|
| 138 |
+
element.textContent = target + (element.dataset.suffix || '');
|
| 139 |
+
clearInterval(timer);
|
| 140 |
+
} else {
|
| 141 |
+
element.textContent = Math.floor(start) + (element.dataset.suffix || '');
|
| 142 |
+
}
|
| 143 |
+
}, 16);
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
// Initialize counters when they come into view
|
| 147 |
+
const counterObserver = new IntersectionObserver((entries) => {
|
| 148 |
+
entries.forEach(entry => {
|
| 149 |
+
if (entry.isIntersecting && !entry.target.classList.contains('counted')) {
|
| 150 |
+
const target = parseInt(entry.target.dataset.target);
|
| 151 |
+
animateCounter(entry.target, target);
|
| 152 |
+
entry.target.classList.add('counted');
|
| 153 |
+
}
|
| 154 |
+
});
|
| 155 |
+
}, { threshold: 0.5 });
|
| 156 |
+
|
| 157 |
+
// Apply counter observer to stat elements
|
| 158 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 159 |
+
document.querySelectorAll('[data-counter]').forEach(el => {
|
| 160 |
+
counterObserver.observe(el);
|
| 161 |
+
});
|
| 162 |
+
});
|
| 163 |
+
|
| 164 |
+
// Mobile menu toggle
|
| 165 |
+
function toggleMobileMenu() {
|
| 166 |
+
const menu = document.querySelector('.mobile-menu');
|
| 167 |
+
menu.classList.toggle('hidden');
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
// Handle theme toggle
|
| 171 |
+
function toggleTheme() {
|
| 172 |
+
document.documentElement.classList.toggle('dark');
|
| 173 |
+
localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light');
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
// Load saved theme
|
| 177 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 178 |
+
const savedTheme = localStorage.getItem('theme');
|
| 179 |
+
if (savedTheme === 'dark') {
|
| 180 |
+
document.documentElement.classList.add('dark');
|
| 181 |
+
}
|
| 182 |
+
});
|
|
@@ -1,28 +1,151 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
margin-top: 0;
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
margin-top: 5px;
|
| 16 |
}
|
| 17 |
|
| 18 |
-
.
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
| 28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700&family=Inter:wght@300;400;600;700&display=swap');
|
| 2 |
+
|
| 3 |
+
@keyframes fadeIn {
|
| 4 |
+
from {
|
| 5 |
+
opacity: 0;
|
| 6 |
+
transform: translateY(20px);
|
| 7 |
+
}
|
| 8 |
+
to {
|
| 9 |
+
opacity: 1;
|
| 10 |
+
transform: translateY(0);
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
@keyframes slideUp {
|
| 15 |
+
from {
|
| 16 |
+
opacity: 0;
|
| 17 |
+
transform: translateY(40px);
|
| 18 |
+
}
|
| 19 |
+
to {
|
| 20 |
+
opacity: 1;
|
| 21 |
+
transform: translateY(0);
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.animate-fade-in {
|
| 26 |
+
animation: fadeIn 0.8s ease-out forwards;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.animate-slide-up {
|
| 30 |
+
animation: slideUp 0.8s ease-out 0.2s forwards;
|
| 31 |
+
opacity: 0;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
/* RTL Support */
|
| 35 |
+
[dir="rtl"] {
|
| 36 |
+
font-family: 'Cairo', sans-serif;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
[dir="ltr"] {
|
| 40 |
+
font-family: 'Inter', sans-serif;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
/* Custom scrollbar */
|
| 44 |
+
::-webkit-scrollbar {
|
| 45 |
+
width: 8px;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
::-webkit-scrollbar-track {
|
| 49 |
+
background: #f1f1f1;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
::-webkit-scrollbar-thumb {
|
| 53 |
+
background: #9C27B0;
|
| 54 |
+
border-radius: 4px;
|
| 55 |
}
|
| 56 |
|
| 57 |
+
::-webkit-scrollbar-thumb:hover {
|
| 58 |
+
background: #7B1FA2;
|
|
|
|
| 59 |
}
|
| 60 |
|
| 61 |
+
/* Ripple effect */
|
| 62 |
+
.ripple {
|
| 63 |
+
position: relative;
|
| 64 |
+
overflow: hidden;
|
|
|
|
| 65 |
}
|
| 66 |
|
| 67 |
+
.ripple:before {
|
| 68 |
+
content: "";
|
| 69 |
+
position: absolute;
|
| 70 |
+
top: 50%;
|
| 71 |
+
left: 50%;
|
| 72 |
+
width: 0;
|
| 73 |
+
height: 0;
|
| 74 |
+
border-radius: 50%;
|
| 75 |
+
background: rgba(255, 255, 255, 0.5);
|
| 76 |
+
transform: translate(-50%, -50%);
|
| 77 |
+
transition: width 0.6s, height 0.6s;
|
| 78 |
}
|
| 79 |
|
| 80 |
+
.ripple:active:before {
|
| 81 |
+
width: 300px;
|
| 82 |
+
height: 300px;
|
| 83 |
}
|
| 84 |
+
|
| 85 |
+
/* Glass morphism effect */
|
| 86 |
+
.glass {
|
| 87 |
+
background: rgba(255, 255, 255, 0.7);
|
| 88 |
+
backdrop-filter: blur(10px);
|
| 89 |
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
/* Gradient text */
|
| 93 |
+
.gradient-text {
|
| 94 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 95 |
+
-webkit-background-clip: text;
|
| 96 |
+
-webkit-text-fill-color: transparent;
|
| 97 |
+
background-clip: text;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
/* Card hover effects */
|
| 101 |
+
.card-hover {
|
| 102 |
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
.card-hover:hover {
|
| 106 |
+
transform: translateY(-4px);
|
| 107 |
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
/* Floating animation */
|
| 111 |
+
@keyframes float {
|
| 112 |
+
0%, 100% {
|
| 113 |
+
transform: translateY(0px);
|
| 114 |
+
}
|
| 115 |
+
50% {
|
| 116 |
+
transform: translateY(-20px);
|
| 117 |
+
}
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
.float-animation {
|
| 121 |
+
animation: float 3s ease-in-out infinite;
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
/* Pulse animation for notifications */
|
| 125 |
+
@keyframes pulse-ring {
|
| 126 |
+
0% {
|
| 127 |
+
transform: scale(0.33);
|
| 128 |
+
}
|
| 129 |
+
40%, 50% {
|
| 130 |
+
opacity: 0;
|
| 131 |
+
}
|
| 132 |
+
100% {
|
| 133 |
+
opacity: 0;
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
.pulse-dot {
|
| 138 |
+
position: relative;
|
| 139 |
+
display: inline-block;
|
| 140 |
+
}
|
| 141 |
+
|
| 142 |
+
.pulse-dot:before {
|
| 143 |
+
content: "";
|
| 144 |
+
position: absolute;
|
| 145 |
+
display: block;
|
| 146 |
+
width: 100%;
|
| 147 |
+
height: 100%;
|
| 148 |
+
border-radius: 50%;
|
| 149 |
+
background: currentColor;
|
| 150 |
+
animation: pulse-ring 1.5s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
|
| 151 |
+
}
|