Commit 2d1d4b4f authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix site-wide critical & medium issues from audit

- CSS: Replace all `vi` units with `vw` for browser compat (tokens.css)
- CSS: Add hex fallbacks before every oklch() usage (~30 instances in pages.css)
- CSS: Remove invalid `lang: ar;`, add 100vh fallback, add [data-reveal] CLS fix (base.css)
- CSS: Add missing --color-primary-dark, --brand-primary, --brand-teal tokens
- JS: Remove broken View Transitions API usage (navigated before transition rendered)
- JS: Fix token name mismatches in injected styles (--color-surface → --bg-surface, etc.)
- JS: Fix exit-intent modal accessibility (aria-label, focus trap, escape key leak)
- HTML: Add OG tags, canonical URL, theme-color to index.html
- HTML: Fix features.html dead anchor links, footer structure, Arabic typo
- HTML: Fix pricing page annual price contradictions, "first 30" consistency
- HTML: Update copyright year to 2025 across all pages
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 45951bbd
......@@ -448,7 +448,7 @@
</div>
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -386,7 +386,7 @@
</div>
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -352,7 +352,7 @@
</div>
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -19,7 +19,6 @@
html {
direction: rtl;
lang: ar;
scroll-behavior: smooth;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
......@@ -50,6 +49,7 @@ body {
color: var(--ink-primary);
background-color: var(--bg-body);
overflow-x: hidden;
min-height: 100vh;
min-height: 100dvh;
}
......@@ -700,3 +700,11 @@ pre code {
padding: 0;
color: inherit;
}
/* ----------------------------------------------------------
CLS Prevention — hide reveal elements before JS runs
---------------------------------------------------------- */
[data-reveal] {
opacity: 0;
}
......@@ -21,6 +21,9 @@
content: '';
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(0,0,0,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.04) 1px, transparent 1px);
background-image:
linear-gradient(oklch(0.4 0.05 240 / 0.04) 1px, transparent 1px),
linear-gradient(90deg, oklch(0.4 0.05 240 / 0.04) 1px, transparent 1px);
......@@ -39,7 +42,9 @@
align-items: center;
gap: 6px;
padding: 4px 12px;
background: rgba(232, 62, 79, 0.1);
background: oklch(0.550 0.180 353.3 / 0.1);
border: 1px solid rgba(232, 62, 79, 0.2);
border: 1px solid oklch(0.550 0.180 353.3 / 0.2);
border-radius: 999px;
font-size: var(--text-xs, 0.75rem);
......@@ -260,7 +265,9 @@
height: 52px;
display: grid;
place-items: center;
background: rgba(232, 62, 79, 0.08);
background: oklch(0.550 0.180 353.3 / 0.08);
border: 1px solid rgba(232, 62, 79, 0.15);
border: 1px solid oklch(0.550 0.180 353.3 / 0.15);
border-radius: var(--radius-lg, 12px);
color: var(--brand-primary, #e83e4f);
......@@ -307,7 +314,9 @@
}
.module-detail__feature-item:hover {
border-color: rgba(232, 62, 79, 0.3);
border-color: oklch(0.550 0.180 353.3 / 0.3);
box-shadow: 0 4px 16px rgba(0,0,0,0.06);
box-shadow: 0 4px 16px oklch(0 0 0 / 0.06);
}
......@@ -317,6 +326,7 @@
height: 32px;
display: grid;
place-items: center;
background: rgba(232, 62, 79, 0.06);
background: oklch(0.550 0.180 353.3 / 0.06);
border-radius: var(--radius-md, 8px);
color: var(--brand-primary, #e83e4f);
......@@ -384,6 +394,7 @@
margin-top: 0.55em;
background: var(--brand-primary, #e83e4f);
border-radius: 50%;
box-shadow: 0 0 6px rgba(232, 62, 79, 0.4);
box-shadow: 0 0 6px oklch(0.550 0.180 353.3 / 0.4);
}
......@@ -537,7 +548,9 @@
height: 36px;
display: grid;
place-items: center;
background: rgba(232, 62, 79, 0.08);
background: oklch(0.550 0.180 353.3 / 0.08);
border: 1px solid rgba(232, 62, 79, 0.15);
border: 1px solid oklch(0.550 0.180 353.3 / 0.15);
border-radius: var(--radius-md, 8px);
color: var(--brand-primary, #e83e4f);
......@@ -679,6 +692,7 @@
}
.pricing-card--featured .pricing-card__header {
background: rgba(20, 184, 166, 0.08);
background: oklch(0.93 0.04 180 / 0.4);
}
......@@ -860,6 +874,7 @@
}
.feature-item:hover {
border-color: rgba(232, 62, 79, 0.3);
border-color: oklch(0.550 0.180 353.3 / 0.3);
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
......@@ -868,6 +883,7 @@
.feature-item__number {
font-size: var(--text-2xl, 1.5rem);
font-weight: 900;
background: linear-gradient(135deg, rgba(232, 62, 79, 0.4), rgba(232, 62, 79, 0.2));
background: linear-gradient(135deg, oklch(0.550 0.180 353.3 / 0.4), oklch(0.550 0.180 353.3 / 0.2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
......@@ -917,7 +933,9 @@
}
.workflow__step:hover {
border-color: rgba(232, 62, 79, 0.3);
border-color: oklch(0.550 0.180 353.3 / 0.3);
box-shadow: 0 0 16px rgba(232, 62, 79, 0.1);
box-shadow: 0 0 16px oklch(0.550 0.180 353.3 / 0.1);
}
......@@ -990,6 +1008,7 @@
top: 0;
inset-inline: 0;
height: 1px;
background: linear-gradient(90deg, transparent 10%, rgba(232, 62, 79, 0.3), transparent 90%);
background: linear-gradient(90deg, transparent 10%, oklch(0.550 0.180 353.3 / 0.3), transparent 90%);
}
......@@ -1017,6 +1036,7 @@
.btn-submit:hover {
background: #c9303f;
transform: translateY(-1px);
box-shadow: 0 6px 20px rgba(232, 62, 79, 0.3);
box-shadow: 0 6px 20px oklch(0.550 0.180 353.3 / 0.3);
}
......@@ -1051,6 +1071,7 @@
.pool-pain-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 32px rgba(0,0,0,0.08);
box-shadow: 0 12px 32px oklch(0 0 0 / 0.08);
}
......@@ -1065,22 +1086,30 @@
}
.pool-pain-card__icon--red {
background: #fde8e8;
background: oklch(0.95 0.04 25);
color: #dc2626;
color: oklch(0.55 0.2 25);
}
.pool-pain-card__icon--amber {
background: #fef3c7;
background: oklch(0.95 0.04 80);
color: #b45309;
color: oklch(0.55 0.15 80);
}
.pool-pain-card__icon--blue {
background: #dfe8f5;
background: oklch(0.93 0.04 230);
color: #6d28d9;
color: oklch(0.50 0.15 230);
}
.pool-pain-card__icon--green {
background: #dff5e8;
background: oklch(0.93 0.05 155);
color: #0f7a3f;
color: oklch(0.45 0.15 155);
}
......@@ -1143,6 +1172,7 @@
width: 1.5rem;
height: 1.5rem;
display: block;
background: #dff5ec;
background: oklch(0.93 0.05 170);
border-radius: var(--radius-full);
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='%23178a5b' stroke-width='3' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
......@@ -1198,23 +1228,32 @@
}
.lane-viz__cell--free {
background: #eef4fa;
background: oklch(0.96 0.02 230);
color: #4a72a8;
color: oklch(0.55 0.1 230);
border: 1px dashed #b3c9e0;
border: 1px dashed oklch(0.8 0.05 230);
}
.lane-viz__cell--booked {
background: #dff5ec;
background: oklch(0.93 0.06 170);
color: #1a6b4a;
color: oklch(0.35 0.12 170);
}
.lane-viz__cell--external {
background: #fdf5e0;
background: oklch(0.93 0.05 60);
color: #8a6d1b;
color: oklch(0.45 0.12 60);
}
.lane-viz__cell--conflict {
background: #fde8e8;
background: oklch(0.93 0.06 25);
color: #b91c1c;
color: oklch(0.45 0.15 25);
animation: pulse-conflict 1.5s ease-in-out infinite;
}
......@@ -1240,6 +1279,7 @@
.screenshot-showcase__item {
border-radius: var(--radius-xl);
overflow: hidden;
box-shadow: 0 4px 24px rgba(0,0,0,0.08);
box-shadow: 0 4px 24px oklch(0 0 0 / 0.08);
border: 1px solid var(--border-subtle);
}
......@@ -1274,11 +1314,13 @@
}
.product-gallery::-webkit-scrollbar-track {
background: #f0f0f0;
background: oklch(0.95 0 0);
border-radius: 3px;
}
.product-gallery::-webkit-scrollbar-thumb {
background: #999999;
background: oklch(0.7 0 0);
border-radius: 3px;
}
......@@ -1288,6 +1330,7 @@
scroll-snap-align: start;
border-radius: var(--radius-xl);
overflow: hidden;
box-shadow: 0 4px 24px rgba(0,0,0,0.08);
box-shadow: 0 4px 24px oklch(0 0 0 / 0.08);
border: 1px solid var(--border-subtle);
background: var(--bg-surface);
......@@ -1309,6 +1352,7 @@
/* Swimming teaser banner */
.swimming-teaser {
background: linear-gradient(135deg, #1a2d4a, #1a3d5c);
background: linear-gradient(135deg, oklch(0.25 0.06 230), oklch(0.30 0.08 200));
border-radius: var(--radius-xl);
padding: var(--space-xl) var(--space-2xl);
......@@ -1358,6 +1402,7 @@
.swimming-teaser__btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0,0,0,0.2);
box-shadow: 0 8px 24px oklch(0 0 0 / 0.2);
}
......@@ -1462,6 +1507,7 @@
}
.compare-full-table .highlight-col {
background: rgba(24, 145, 178, 0.05);
background: oklch(0.55 0.15 200 / 0.05);
}
......@@ -1539,6 +1585,7 @@
.blog-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
box-shadow: 0 8px 24px oklch(0 0 0 / 0.08);
}
......@@ -1601,6 +1648,7 @@
width: 48px;
height: 48px;
margin: 0 auto var(--space-md);
background: #e0f2f7;
background: oklch(0.93 0.05 200);
border-radius: var(--radius-lg);
display: grid;
......@@ -1641,10 +1689,12 @@
width: 56px;
height: 56px;
margin: 0 auto var(--space-md);
background: #fdf0d5;
background: oklch(0.93 0.04 45);
border-radius: var(--radius-full);
display: grid;
place-items: center;
color: #b45309;
color: oklch(0.50 0.15 45);
}
......@@ -1683,6 +1733,7 @@
height: 16px;
flex-shrink: 0;
margin-top: 2px;
background: #dff5ec;
background: oklch(0.93 0.05 170);
border-radius: 50%;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='%23178a5b' stroke-width='3' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
......
......@@ -14,6 +14,7 @@
/* Primary — Navy */
--color-primary: #1B2B4B;
--color-primary-dark: #15294a;
--color-primary-light: #2D4A7C;
--color-primary-dim: #162340;
--color-primary-ghost: rgba(27, 43, 75, 0.06);
......@@ -100,29 +101,29 @@
--tracking-widest: 0.08em;
/* Type scale */
--text-xs: clamp(0.694rem, 0.60vi + 0.55rem, 0.75rem);
--text-sm: clamp(0.833rem, 0.70vi + 0.65rem, 0.875rem);
--text-base: clamp(0.938rem, 0.80vi + 0.70rem, 1rem);
--text-lg: clamp(1.063rem, 1.00vi + 0.75rem, 1.125rem);
--text-xl: clamp(1.200rem, 1.20vi + 0.80rem, 1.375rem);
--text-2xl: clamp(1.440rem, 1.60vi + 0.90rem, 1.750rem);
--text-3xl: clamp(1.728rem, 2.20vi + 1.00rem, 2.250rem);
--text-4xl: clamp(2.074rem, 3.00vi + 1.10rem, 2.813rem);
--text-5xl: clamp(2.488rem, 4.00vi + 1.20rem, 3.500rem);
--text-xs: clamp(0.694rem, 0.60vw + 0.55rem, 0.75rem);
--text-sm: clamp(0.833rem, 0.70vw + 0.65rem, 0.875rem);
--text-base: clamp(0.938rem, 0.80vw + 0.70rem, 1rem);
--text-lg: clamp(1.063rem, 1.00vw + 0.75rem, 1.125rem);
--text-xl: clamp(1.200rem, 1.20vw + 0.80rem, 1.375rem);
--text-2xl: clamp(1.440rem, 1.60vw + 0.90rem, 1.750rem);
--text-3xl: clamp(1.728rem, 2.20vw + 1.00rem, 2.250rem);
--text-4xl: clamp(2.074rem, 3.00vw + 1.10rem, 2.813rem);
--text-5xl: clamp(2.488rem, 4.00vw + 1.20rem, 3.500rem);
/* ----------------------------------------------------------
Spacing
Base: 4px · Fluid clamp() scale
---------------------------------------------------------- */
--space-2xs: clamp(0.125rem, 0.20vi, 0.25rem); /* 2–4px */
--space-xs: clamp(0.25rem, 0.40vi, 0.50rem); /* 4–8px */
--space-sm: clamp(0.50rem, 0.80vi, 0.75rem); /* 8–12px */
--space-md: clamp(0.75rem, 1.20vi, 1.25rem); /* 12–20px */
--space-lg: clamp(1.25rem, 2.00vi, 2.00rem); /* 20–32px */
--space-xl: clamp(2.00rem, 3.50vi, 3.00rem); /* 32–48px */
--space-2xl: clamp(3.00rem, 5.50vi, 5.00rem); /* 48–80px */
--space-3xl: clamp(5.00rem, 8.00vi, 7.00rem); /* 80–112px */
--space-section: clamp(5.00rem, 9.00vi, 8.00rem); /* section padding */
--space-2xs: clamp(0.125rem, 0.20vw, 0.25rem); /* 2–4px */
--space-xs: clamp(0.25rem, 0.40vw, 0.50rem); /* 4–8px */
--space-sm: clamp(0.50rem, 0.80vw, 0.75rem); /* 8–12px */
--space-md: clamp(0.75rem, 1.20vw, 1.25rem); /* 12–20px */
--space-lg: clamp(1.25rem, 2.00vw, 2.00rem); /* 20–32px */
--space-xl: clamp(2.00rem, 3.50vw, 3.00rem); /* 32–48px */
--space-2xl: clamp(3.00rem, 5.50vw, 5.00rem); /* 48–80px */
--space-3xl: clamp(5.00rem, 8.00vw, 7.00rem); /* 80–112px */
--space-section: clamp(5.00rem, 9.00vw, 8.00rem); /* section padding */
/* ----------------------------------------------------------
Border Radius — Conservative, professional
......@@ -208,4 +209,10 @@
--card-padding: var(--space-lg);
--card-shadow: var(--shadow-sm);
--card-shadow-hover: var(--shadow-md);
/* ----------------------------------------------------------
Brand Aliases
---------------------------------------------------------- */
--brand-primary: var(--color-primary);
--brand-teal: var(--color-accent);
}
......@@ -206,7 +206,7 @@
<div class="module-detail__list-item">عروض ترويجية وكوبونات مع شروط وتواريخ انتهاء</div>
<div class="module-detail__list-item">تسعير موسمي ومرتبط بالفرع أو وقت اليوم</div>
<div class="module-detail__list-item">حد أقصى للخصم لا يُتجاوز أبداً</div>
<div class="module-detail__list-item">تجميد السعر على الفاتورة — التغييرات لا تأثر على الفواتير القديمة</div>
<div class="module-detail__list-item">تجميد السعر على الفاتورة — التغييرات لا تؤثر على الفواتير القديمة</div>
</div>
</div>
<div style="padding: var(--space-2xl); background: var(--bg-surface); border: 1px solid var(--border-subtle); border-radius: var(--radius-xl);" data-reveal="150">
......@@ -479,8 +479,8 @@
<div class="feature-card__icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="5" y="2" width="14" height="20" rx="2"/><path d="M12 18h.01"/></svg>
</div>
<h3 class="feature-card__title">تطبيقات للمدربين وأولياء الأمور</h3>
<p class="feature-card__text">تطبيق للمدرب لتسجيل الحضور والتقييم. تطبيق لولي الأمر لمتابعة أبنائه والمدفوعات والجداول.</p>
<h3 class="feature-card__title">بوابة إلكترونية للمدربين وأولياء الأمور</h3>
<p class="feature-card__text">واجهة للمدرب لتسجيل الحضور والتقييم. واجهة لولي الأمر لمتابعة أبنائه والمدفوعات والجداول.</p>
</div>
<div class="feature-card" data-reveal="250">
......@@ -531,37 +531,48 @@
<div class="container">
<div class="footer__grid">
<div class="footer__brand">
<div class="footer__brand-name">El-Captain</div>
<p class="footer__brand-desc">نظام إدارة متكامل مصمم خصيصاً للأكاديميات الرياضية في مصر. يغطي كل العمليات من تسجيل المشترك حتى التقارير المالية الشهرية.</p>
<a href="/" class="footer__brand-logo">
<span class="footer__brand-mark">EC</span>
<span class="footer__brand-name">El-Captain</span>
</a>
<p class="footer__brand-desc">نظام إدارة متكامل مبني خصيصاً للأكاديميات الرياضية في مصر. يغطي كل العمليات من التسجيل حتى التقارير المالية.</p>
</div>
<div>
<h4 class="footer__col-title">الوحدات</h4>
<a href="features.html#members" class="footer__link">العضويات</a>
<a href="features.html#sports" class="footer__link">الأنشطة الرياضية</a>
<a href="features.html#pool" class="footer__link">حمامات السباحة</a>
<a href="features.html#finance" class="footer__link">المالية</a>
<a href="features.html" class="footer__link">كل المزايا</a>
<h4 class="footer__col-title">النظام</h4>
<div class="footer__links">
<a href="features.html#participants" class="footer__link">إدارة المشتركين</a>
<a href="features.html#programs" class="footer__link">الأنشطة والبرامج</a>
<a href="features.html#finance" class="footer__link">المالية والمحاسبة</a>
<a href="features.html#attendance" class="footer__link">الحضور الذكي</a>
<a href="features.html#inventory" class="footer__link">المخازن</a>
<a href="features.html#hr" class="footer__link">الموارد البشرية</a>
</div>
</div>
<div>
<h4 class="footer__col-title">النظام</h4>
<a href="features.html#hr" class="footer__link">الموارد البشرية</a>
<a href="features.html#inventory" class="footer__link">المخازن</a>
<a href="features.html#reports" class="footer__link">التقارير</a>
<a href="features.html#mobile" class="footer__link">التطبيقات</a>
<h4 class="footer__col-title">روابط سريعة</h4>
<div class="footer__links">
<a href="features.html" class="footer__link">كل المزايا</a>
<a href="swimming.html" class="footer__link">أكاديميات السباحة</a>
<a href="pricing.html" class="footer__link">التسعير</a>
<a href="contact.html" class="footer__link">تواصل معنا</a>
</div>
</div>
<div>
<h4 class="footer__col-title">تواصل</h4>
<a href="contact.html" class="footer__link">اطلب عرض</a>
<a href="contact.html" class="footer__link">الدعم الفني</a>
<div class="footer__links">
<a href="contact.html" class="footer__link">احجز عرض تجريبي</a>
<a href="https://wa.me/201XXXXXXXXX" class="footer__link" target="_blank" rel="noopener">WhatsApp</a>
<a href="contact.html" class="footer__link">الدعم الفني</a>
</div>
</div>
</div>
<div class="footer__bottom">
<span>El-Captain ERP System</span>
<span>نظام إدارة الأكاديميات الرياضية</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
</footer>
......
......@@ -1158,7 +1158,7 @@
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -856,7 +856,7 @@
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -5,6 +5,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>El-Captain — نظام إدارة الأكاديميات الرياضية</title>
<meta name="description" content="نظام متكامل لإدارة الأكاديميات الرياضية — مشتركين، مالية، حضور، جداول، ومخازن.">
<meta property="og:title" content="El-Captain — نظام إدارة الأكاديميات الرياضية">
<meta property="og:description" content="نظام ERP متكامل للأكاديميات الرياضية: مشتركين، مالية، حضور، جداول، مخازن. كل اللي أكاديميتك محتاجاه في مكان واحد.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://el-captain-website.caprover.al-arcade.com/">
<meta property="og:locale" content="ar_EG">
<link rel="canonical" href="https://el-captain-website.caprover.al-arcade.com/">
<meta name="theme-color" content="#1B2B4B">
<link rel="stylesheet" href="css/tokens.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/components.css">
......@@ -167,7 +174,7 @@
</div>
</div>
<div class="footer__bottom">
<span>&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span>&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
</div>
</div>
</footer>
......
......@@ -611,6 +611,7 @@ function initExitIntent() {
type="tel"
class="exit-modal__input"
placeholder="رقم الموبايل (01xxxxxxxxx)"
aria-label="البريد الإلكتروني"
dir="ltr"
required
pattern="01[0-9]{9}"
......@@ -628,20 +629,24 @@ function initExitIntent() {
modal.classList.add('exit-modal--visible');
});
// Close handlers
// Focus the input for accessibility
setTimeout(() => modal.querySelector('input').focus(), 100);
// Escape key handler (shared reference so it can be removed from all close paths)
function onEscapeKey(ev) {
if (ev.key === 'Escape') closeModal();
}
// Close handlers — shared function removes listener to prevent leak
const closeModal = () => {
document.removeEventListener('keydown', onEscapeKey);
modal.classList.remove('exit-modal--visible');
setTimeout(() => modal.remove(), 300);
};
modal.querySelector('.exit-modal__close').addEventListener('click', closeModal);
modal.querySelector('.exit-modal__backdrop').addEventListener('click', closeModal);
document.addEventListener('keydown', function handler(ev) {
if (ev.key === 'Escape') {
closeModal();
document.removeEventListener('keydown', handler);
}
});
document.addEventListener('keydown', onEscapeKey);
// Form submit — open WhatsApp with pre-filled message
modal.querySelector('#exitIntentForm').addEventListener('submit', (ev) => {
......@@ -838,35 +843,8 @@ function initMicroInteractions() {
Only if browser supports document.startViewTransition.
═══════════════════════════════════════════════ */
function initPageTransitions() {
if (!document.startViewTransition) return;
document.addEventListener('click', (e) => {
const link = e.target.closest('a[href]');
if (!link) return;
const href = link.getAttribute('href');
if (!href) return;
// Skip anchor links, external links, target=_blank, downloads
if (href.startsWith('#')) return;
if (link.target === '_blank') return;
if (link.hasAttribute('download')) return;
if (link.dataset.noTransition !== undefined) return;
// Check if internal link (same origin)
try {
const url = new URL(href, window.location.origin);
if (url.origin !== window.location.origin) return;
} catch {
return;
}
e.preventDefault();
document.startViewTransition(() => {
window.location.href = href;
});
});
// Removed: View Transitions API usage was navigating away before transition rendered.
// Links navigate normally without interception.
}
/* ═══════════════════════════════════════════════
......@@ -962,7 +940,7 @@ function injectDynamicStyles() {
width: 280px;
height: 100vh;
height: 100dvh;
background: var(--color-surface, #fff);
background: var(--bg-surface, #fff);
transform: translateX(100%);
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 999;
......@@ -1056,7 +1034,7 @@ function injectDynamicStyles() {
}
.exit-modal__content {
position: relative;
background: var(--color-surface, #fff);
background: var(--bg-surface, #fff);
border-radius: 16px;
padding: 2.5rem 2rem;
max-width: 420px;
......@@ -1076,7 +1054,7 @@ function injectDynamicStyles() {
background: none;
border: none;
font-size: 1.75rem;
color: var(--color-text-muted, #666);
color: var(--ink-muted, #666);
cursor: pointer;
line-height: 1;
padding: 0.25rem 0.5rem;
......@@ -1084,17 +1062,17 @@ function injectDynamicStyles() {
transition: color 0.2s;
}
.exit-modal__close:hover {
color: var(--color-text, #333);
color: var(--ink-primary, #333);
}
.exit-modal__title {
font-size: 1.5rem;
font-weight: 800;
margin-bottom: 0.5rem;
color: var(--color-text, #1e293b);
color: var(--ink-primary, #1e293b);
}
.exit-modal__subtitle {
font-size: 1rem;
color: var(--color-text-muted, #64748b);
color: var(--ink-muted, #64748b);
margin-bottom: 1.5rem;
}
.exit-modal__field {
......@@ -1103,7 +1081,7 @@ function injectDynamicStyles() {
.exit-modal__input {
width: 100%;
padding: 0.75rem 1rem;
border: 2px solid var(--color-border, #e2e8f0);
border: 2px solid var(--border-subtle, #e2e8f0);
border-radius: 8px;
font-size: 1rem;
text-align: center;
......@@ -1127,7 +1105,7 @@ function injectDynamicStyles() {
transition: background 0.2s, transform 0.2s;
}
.exit-modal__submit:hover {
background: var(--color-primary-dark, #15294a);
background: var(--color-primary-dim, #15294a);
transform: translateY(-1px);
}
......@@ -1157,7 +1135,7 @@ function injectDynamicStyles() {
transform: scale(1);
}
.back-to-top:hover {
background: var(--color-primary-dark, #15294a);
background: var(--color-primary-dim, #15294a);
transform: scale(1.1);
}
.back-to-top:active {
......@@ -1173,7 +1151,7 @@ function injectDynamicStyles() {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 1rem;
color: var(--color-text, #1e293b);
color: var(--ink-primary, #1e293b);
}
.pricing-calc__value {
color: var(--color-primary, #1e3a5f);
......@@ -1184,7 +1162,7 @@ function injectDynamicStyles() {
height: 8px;
border-radius: 4px;
appearance: none;
background: var(--color-border, #e2e8f0);
background: var(--border-subtle, #e2e8f0);
outline: none;
cursor: pointer;
}
......@@ -1214,7 +1192,7 @@ function injectDynamicStyles() {
display: flex;
justify-content: space-between;
font-size: 0.8rem;
color: var(--color-text-muted, #64748b);
color: var(--ink-muted, #64748b);
margin-top: 0.5rem;
margin-bottom: 1.5rem;
}
......@@ -1225,7 +1203,7 @@ function injectDynamicStyles() {
.pricing-calc__plan {
position: relative;
padding: 1rem 1.25rem;
border: 2px solid var(--color-border, #e2e8f0);
border: 2px solid var(--border-subtle, #e2e8f0);
border-radius: 12px;
transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
}
......@@ -1238,13 +1216,13 @@ function injectDynamicStyles() {
font-weight: 700;
font-size: 1rem;
margin-bottom: 0.25rem;
color: var(--color-text, #1e293b);
color: var(--ink-primary, #1e293b);
}
.pricing-calc__plan-breakdown {
display: flex;
gap: 1rem;
font-size: 0.85rem;
color: var(--color-text-muted, #64748b);
color: var(--ink-muted, #64748b);
margin-bottom: 0.5rem;
flex-wrap: wrap;
}
......@@ -1301,24 +1279,6 @@ function injectDynamicStyles() {
100% { transform: scale(1); }
}
/* ── View Transitions ── */
@view-transition {
navigation: auto;
}
::view-transition-old(root) {
animation: fadeOut 0.2s ease-out;
}
::view-transition-new(root) {
animation: fadeIn 0.2s ease-in;
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
`;
document.head.appendChild(style);
}
......@@ -1147,7 +1147,7 @@
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
......@@ -489,7 +489,7 @@
<!-- Value Frame Banner -->
<div class="value-frame" data-reveal>
<div class="value-frame__headline">سعر النظام ٢٥٠,٠٠٠ ج.م — أول ٣٠ مشترك يبدأوا برسوم الدعم والاستضافة فقط</div>
<div class="value-frame__sub">٤٩ ج.م لكل لاعب في الشهر (لأكاديمية ٥٠ لاعب)</div>
<div class="value-frame__sub" data-eg-compare="٤٩ ج.م لكل لاعب في الشهر (لأكاديمية ٥٠ لاعب)" data-sa-compare="٢٠ ر.س لكل لاعب في الشهر (لأكاديمية ٥٠ لاعب)">٤٩ ج.م لكل لاعب في الشهر (لأكاديمية ٥٠ لاعب)</div>
<div class="value-frame__early">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
أوائل المشتركين يقفلون على السعر ده للأبد
......@@ -521,7 +521,7 @@
</div>
<ul class="plan-card__features">
<li>كل مزايا النظام بدون استثناء</li>
<li>المزايا الأساسية كاملة</li>
<li>إدارة المشتركين والحضور</li>
<li>الفواتير والمدفوعات</li>
<li>البرامج والمجموعات والجداول</li>
......@@ -636,21 +636,21 @@
<!-- Annual pricing (10 months only) -->
<div style="margin-top: var(--space-lg); padding-top: var(--space-lg); border-top: 1px solid var(--border-subtle);">
<div style="font-size: var(--text-base); font-weight: 700; color: var(--ink-primary); margin-bottom: var(--space-sm);">الاشتراك السنوي = ١٠ شهور فقط (شهرين مجاناً)</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md); margin-top: var(--space-md);">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); gap: var(--space-md); margin-top: var(--space-md);">
<div style="text-align: center; padding: var(--space-md); background: var(--bg-muted); border-radius: var(--radius-lg);">
<div style="font-size: var(--text-xs); color: var(--ink-muted); margin-bottom: 4px;">الصغيرة سنوياً</div>
<div style="font-size: var(--text-lg); font-weight: 800; color: var(--ink-primary);" data-eg-compare="٦,٩٩٠ ج.م" data-sa-compare="٢,٩٩٠ ر.س">٦,٩٩٠ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);">وفّر ١,٣٩٨ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);" data-eg-compare="وفّر ١,٣٩٨ ج.م" data-sa-compare="وفّر ٥٩٨ ر.س">وفّر ١,٣٩٨ ج.م</div>
</div>
<div style="text-align: center; padding: var(--space-md); background: var(--bg-muted); border-radius: var(--radius-lg);">
<div style="font-size: var(--text-xs); color: var(--ink-muted); margin-bottom: 4px;">المتوسطة سنوياً</div>
<div style="font-size: var(--text-lg); font-weight: 800; color: var(--ink-primary);" data-eg-compare="١٤,٩٩٠ ج.م" data-sa-compare="٦,٩٩٠ ر.س">١٤,٩٩٠ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);">وفّر ٢,٩٩٨ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);" data-eg-compare="وفّر ٢,٩٩٨ ج.م" data-sa-compare="وفّر ١,٣٩٨ ر.س">وفّر ٢,٩٩٨ ج.م</div>
</div>
<div style="text-align: center; padding: var(--space-md); background: var(--bg-muted); border-radius: var(--radius-lg);">
<div style="font-size: var(--text-xs); color: var(--ink-muted); margin-bottom: 4px;">الكبيرة سنوياً</div>
<div style="font-size: var(--text-lg); font-weight: 800; color: var(--ink-primary);" data-eg-compare="٣٤,٩٩٠ ج.م" data-sa-compare="١٤,٩٩٠ ر.س">٣٤,٩٩٠ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);">وفّر ٦,٩٩٨ ج.م</div>
<div style="font-size: var(--text-xs); color: var(--color-success);" data-eg-compare="وفّر ٦,٩٩٨ ج.م" data-sa-compare="وفّر ٢,٩٩٨ ر.س">وفّر ٦,٩٩٨ ج.م</div>
</div>
</div>
<div style="font-size: var(--text-xs); color: var(--ink-muted); text-align: center; margin-top: var(--space-sm);">+ دومين خاص مجاناً مع الاشتراك السنوي</div>
......@@ -783,9 +783,9 @@
</tr>
<tr>
<td>اشتراك سنوي</td>
<td dir="ltr"><span data-eg-compare="5,999" data-sa-compare="2,699">5,999</span> <span class="compare-currency">ج.م</span></td>
<td class="featured-col" dir="ltr"><span data-eg-compare="13,499" data-sa-compare="5,999">13,499</span> <span class="compare-currency">ج.م</span></td>
<td dir="ltr"><span data-eg-compare="29,999" data-sa-compare="12,999">29,999</span> <span class="compare-currency">ج.م</span></td>
<td dir="ltr"><span data-eg-compare="6,990" data-sa-compare="2,990">6,990</span> <span class="compare-currency">ج.م</span></td>
<td class="featured-col" dir="ltr"><span data-eg-compare="14,990" data-sa-compare="6,990">14,990</span> <span class="compare-currency">ج.م</span></td>
<td dir="ltr"><span data-eg-compare="34,990" data-sa-compare="14,990">34,990</span> <span class="compare-currency">ج.م</span></td>
</tr>
<tr>
<td>رسوم التفعيل</td>
......@@ -900,7 +900,7 @@
</div>
<div style="background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-lg); padding: var(--space-lg);">
<h4 style="margin-bottom: var(--space-xs); color: var(--ink-primary);">ما هو عرض "أوائل المشتركين"؟</h4>
<p style="color: var(--ink-secondary); font-size: var(--text-sm); line-height: 1.8;">أوائل المشتركين (أول 50 أكاديمية) يقفلون على السعر الحالي للأبد — حتى لو زادت الأسعار لاحقاً. السعر المعروض اليوم هو سعرك الدائم.</p>
<p style="color: var(--ink-secondary); font-size: var(--text-sm); line-height: 1.8;">أوائل المشتركين (أول ٣٠ أكاديمية) يقفلون على السعر الحالي للأبد — حتى لو زادت الأسعار لاحقاً. السعر المعروض اليوم هو سعرك الدائم.</p>
</div>
<div style="background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-lg); padding: var(--space-lg);">
<h4 style="margin-bottom: var(--space-xs); color: var(--ink-primary);">هل الاشتراك السنوي أوفر؟</h4>
......
......@@ -1113,7 +1113,7 @@
</div>
<div class="footer__bottom">
<span class="footer__copy">&copy; 2024 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">&copy; 2025 El-Captain. جميع الحقوق محفوظة.</span>
<span class="footer__copy">نظام إدارة الأكاديميات الرياضية</span>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment