Commit 081d9938 authored by Mahmoud Aglan's avatar Mahmoud Aglan

kokokokoko

parent 8c142ce1
......@@ -32,7 +32,7 @@ html {
body {
font-family: 'Tajawal', sans-serif;
font-size: var(--text-base);
line-height: 1.7;
line-height: 1.75;
color: var(--ink-primary);
background-color: var(--bg-deep);
overflow-x: hidden;
......@@ -40,14 +40,15 @@ body {
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.25;
line-height: 1.2;
font-weight: 700;
text-wrap: balance;
letter-spacing: -0.01em;
}
h1 { font-size: var(--text-5xl); font-weight: 900; }
h2 { font-size: var(--text-4xl); font-weight: 800; }
h3 { font-size: var(--text-3xl); }
h1 { font-size: var(--text-5xl); font-weight: 900; letter-spacing: -0.025em; line-height: 1.05; }
h2 { font-size: var(--text-4xl); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
h3 { font-size: var(--text-3xl); letter-spacing: -0.015em; }
h4 { font-size: var(--text-2xl); }
h5 { font-size: var(--text-xl); }
......@@ -86,7 +87,7 @@ ul, ol {
}
::selection {
background: oklch(0.570 0.158 353.3 / 0.3);
background: oklch(0.550 0.180 353.3 / 0.35);
color: var(--ink-primary);
}
......@@ -109,6 +110,7 @@ ul, ol {
.section {
padding-block: var(--space-section);
position: relative;
}
.visually-hidden {
......@@ -122,3 +124,14 @@ ul, ol {
white-space: nowrap;
border: 0;
}
/* Noise texture overlay for depth */
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
opacity: 0.025;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}
This diff is collapsed.
This diff is collapsed.
/* Module detail pages */
.module-detail__features {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: var(--space-lg);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
gap: var(--space-md);
}
.module-detail__screenshot-section {
......@@ -42,25 +42,27 @@
display: flex;
align-items: flex-start;
gap: var(--space-sm);
font-size: var(--text-base);
font-size: var(--text-sm);
color: var(--ink-secondary);
line-height: 1.7;
}
.module-detail__list-item::before {
content: '';
flex-shrink: 0;
width: 6px;
height: 6px;
margin-top: 0.65em;
width: 5px;
height: 5px;
margin-top: 0.6em;
background: var(--brand-primary);
border-radius: 50%;
box-shadow: 0 0 6px oklch(0.550 0.180 353.3 / 0.4);
}
/* Features overview page */
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
gap: var(--space-lg);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: var(--space-md);
}
.feature-item {
......@@ -70,27 +72,41 @@
padding: var(--space-xl);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
align-items: start;
transition: all var(--duration-slow) var(--ease-out-expo);
position: relative;
overflow: hidden;
}
.feature-item:hover {
border-color: var(--border-glow);
transform: translateY(-2px);
box-shadow: 0 8px 32px oklch(0 0 0 / 0.2);
}
.feature-item__number {
font-size: var(--text-3xl);
font-size: var(--text-2xl);
font-weight: 900;
color: var(--brand-primary-dim);
background: linear-gradient(135deg, var(--brand-primary-dim), var(--brand-primary-muted));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
line-height: 1;
opacity: 0.6;
opacity: 0.7;
}
.feature-item__content h4 {
font-size: var(--text-lg);
margin-bottom: var(--space-xs);
font-size: var(--text-base);
font-weight: 700;
margin-bottom: var(--space-2xs);
color: var(--ink-primary);
}
.feature-item__content p {
font-size: var(--text-sm);
color: var(--ink-secondary);
line-height: 1.8;
}
/* Contact / Pricing page */
......@@ -116,7 +132,7 @@
.form-group {
display: flex;
flex-direction: column;
gap: var(--space-xs);
gap: var(--space-2xs);
}
.form-group label {
......@@ -128,14 +144,15 @@
.form-group input,
.form-group textarea,
.form-group select {
padding: var(--space-md);
padding: var(--space-sm) var(--space-md);
background: var(--bg-surface);
border: 1px solid var(--border-default);
border-radius: var(--radius-md);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
color: var(--ink-primary);
font-family: inherit;
font-size: var(--text-base);
transition: border-color var(--duration-fast) var(--ease-out-quart);
font-size: var(--text-sm);
transition: all var(--duration-fast) var(--ease-out-quart);
min-height: 44px;
}
.form-group input:focus,
......@@ -143,19 +160,33 @@
.form-group select:focus {
outline: none;
border-color: var(--brand-primary);
box-shadow: 0 0 0 3px oklch(0.570 0.158 353.3 / 0.15);
box-shadow: 0 0 0 3px oklch(0.550 0.180 353.3 / 0.1), 0 0 20px oklch(0.550 0.180 353.3 / 0.05);
background: var(--bg-elevated);
}
.form-group input::placeholder,
.form-group textarea::placeholder {
color: var(--ink-muted);
}
.form-group textarea {
min-height: 150px;
min-height: 120px;
resize: vertical;
}
.form-group select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23888' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: left 12px center;
padding-left: 36px;
}
.contact-info {
padding: var(--space-xl);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
}
.contact-info__item {
......@@ -170,24 +201,25 @@
}
.contact-info__icon {
width: 2.5rem;
height: 2.5rem;
width: 2.25rem;
height: 2.25rem;
display: grid;
place-items: center;
background: oklch(0.570 0.158 353.3 / 0.1);
background: oklch(0.550 0.180 353.3 / 0.08);
border: 1px solid oklch(0.550 0.180 353.3 / 0.15);
border-radius: var(--radius-md);
color: var(--brand-primary-light);
flex-shrink: 0;
}
.contact-info__label {
font-size: var(--text-sm);
font-size: var(--text-xs);
color: var(--ink-muted);
margin-bottom: 2px;
}
.contact-info__value {
font-size: var(--text-base);
font-size: var(--text-sm);
color: var(--ink-primary);
font-weight: 500;
}
......@@ -196,7 +228,7 @@
.workflow {
display: flex;
align-items: center;
gap: var(--space-md);
gap: var(--space-sm);
flex-wrap: wrap;
justify-content: center;
padding: var(--space-xl) 0;
......@@ -205,19 +237,27 @@
.workflow__step {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-md) var(--space-lg);
gap: var(--space-xs);
padding: var(--space-sm) var(--space-md);
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-md);
border-radius: var(--radius-lg);
font-size: var(--text-sm);
font-weight: 500;
color: var(--ink-primary);
transition: all var(--duration-normal) var(--ease-out-quart);
white-space: nowrap;
}
.workflow__step:hover {
border-color: var(--border-glow);
box-shadow: 0 0 16px oklch(0.550 0.180 353.3 / 0.1);
}
.workflow__arrow {
color: var(--brand-primary-dim);
font-size: var(--text-xl);
font-size: var(--text-lg);
opacity: 0.6;
}
/* Comparison table */
......@@ -225,15 +265,15 @@
width: 100%;
border-collapse: collapse;
background: var(--bg-surface);
border-radius: var(--radius-lg);
border-radius: var(--radius-xl);
overflow: hidden;
border: 1px solid var(--border-subtle);
}
.comparison-table th {
padding: var(--space-md) var(--space-lg);
padding: var(--space-sm) var(--space-md);
background: var(--bg-elevated);
font-weight: 700;
font-weight: 600;
font-size: var(--text-sm);
color: var(--ink-primary);
text-align: right;
......@@ -241,10 +281,15 @@
}
.comparison-table td {
padding: var(--space-md) var(--space-lg);
padding: var(--space-sm) var(--space-md);
font-size: var(--text-sm);
color: var(--ink-secondary);
border-bottom: 1px solid var(--border-subtle);
border-bottom: 1px solid oklch(1 0 0 / 0.02);
transition: background var(--duration-fast) var(--ease-out-quart);
}
.comparison-table tr:hover td {
background: oklch(1 0 0 / 0.02);
}
.comparison-table tr:last-child td {
......@@ -258,5 +303,16 @@
.comparison-table .cross {
color: var(--ink-muted);
opacity: 0.5;
opacity: 0.4;
}
/* Gradient section dividers */
.section--gradient-top::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent 10%, var(--brand-primary-dim), transparent 90%);
}
:root {
/* Brand seed: oklch(0.570 0.158 353.3) — deep rose/crimson */
--brand-primary: oklch(0.570 0.158 353.3);
--brand-primary-light: oklch(0.650 0.140 353.3);
--brand-primary-dim: oklch(0.450 0.120 353.3);
--brand-primary-muted: oklch(0.380 0.080 353.3);
--brand-primary: oklch(0.550 0.180 353.3);
--brand-primary-light: oklch(0.680 0.160 353.3);
--brand-primary-dim: oklch(0.400 0.130 353.3);
--brand-primary-muted: oklch(0.320 0.090 353.3);
--brand-primary-ghost: oklch(0.570 0.158 353.3 / 0.06);
/* Backgrounds — true dark, not warm-tinted */
--bg-deep: oklch(0.120 0.008 353.3);
--bg-base: oklch(0.150 0.010 353.3);
--bg-surface: oklch(0.185 0.012 353.3);
--bg-elevated: oklch(0.220 0.014 353.3);
/* Backgrounds — deeper, colder dark */
--bg-deep: oklch(0.095 0.006 280);
--bg-base: oklch(0.115 0.008 280);
--bg-surface: oklch(0.145 0.010 280);
--bg-elevated: oklch(0.180 0.012 280);
/* Text */
--ink-primary: oklch(0.950 0.005 353.3);
--ink-secondary: oklch(0.750 0.010 353.3);
--ink-muted: oklch(0.550 0.008 353.3);
--ink-primary: oklch(0.960 0.003 280);
--ink-secondary: oklch(0.720 0.008 280);
--ink-muted: oklch(0.500 0.006 280);
/* Borders */
--border-subtle: oklch(0.250 0.012 353.3);
--border-default: oklch(0.320 0.015 353.3);
--border-subtle: oklch(0.200 0.010 280);
--border-default: oklch(0.280 0.012 280);
--border-glow: oklch(0.550 0.180 353.3 / 0.25);
/* Accent — gold for secondary highlights */
--accent-gold: oklch(0.700 0.120 85);
/* Accent — warm gold for secondary */
--accent-gold: oklch(0.750 0.130 85);
--accent-gold-dim: oklch(0.550 0.090 85);
/* Functional */
......@@ -32,45 +34,54 @@
/* Typography scale — 1.333 ratio (perfect fourth) */
--text-xs: clamp(0.694rem, 0.65vi + 0.5rem, 0.75rem);
--text-sm: clamp(0.833rem, 0.8vi + 0.6rem, 0.875rem);
--text-base: clamp(1rem, 1vi + 0.7rem, 1.063rem);
--text-lg: clamp(1.125rem, 1.2vi + 0.8rem, 1.25rem);
--text-xl: clamp(1.333rem, 1.5vi + 0.9rem, 1.5rem);
--text-2xl: clamp(1.777rem, 2.2vi + 1rem, 2.25rem);
--text-3xl: clamp(2.369rem, 3vi + 1.2rem, 3rem);
--text-4xl: clamp(3.157rem, 4vi + 1.5rem, 4rem);
--text-5xl: clamp(4.209rem, 5.5vi + 1.8rem, 5.5rem);
--text-base: clamp(0.938rem, 0.9vi + 0.65rem, 1rem);
--text-lg: clamp(1.063rem, 1.1vi + 0.75rem, 1.188rem);
--text-xl: clamp(1.25rem, 1.4vi + 0.85rem, 1.375rem);
--text-2xl: clamp(1.6rem, 2vi + 0.95rem, 2rem);
--text-3xl: clamp(2.1rem, 2.8vi + 1.1rem, 2.75rem);
--text-4xl: clamp(2.8rem, 3.5vi + 1.3rem, 3.5rem);
--text-5xl: clamp(3.4rem, 4.5vi + 1.5rem, 4.5rem);
/* Spacing */
--space-2xs: clamp(0.125rem, 0.25vi, 0.25rem);
--space-xs: clamp(0.25rem, 0.5vi, 0.5rem);
--space-sm: clamp(0.5rem, 1vi, 0.75rem);
--space-md: clamp(1rem, 2vi, 1.5rem);
--space-lg: clamp(1.5rem, 3vi, 2.5rem);
--space-xl: clamp(2.5rem, 5vi, 4rem);
--space-2xl: clamp(4rem, 8vi, 6rem);
--space-3xl: clamp(6rem, 12vi, 10rem);
--space-md: clamp(0.875rem, 1.5vi, 1.25rem);
--space-lg: clamp(1.25rem, 2.5vi, 2rem);
--space-xl: clamp(2rem, 4vi, 3rem);
--space-2xl: clamp(3rem, 6vi, 5rem);
--space-3xl: clamp(5rem, 10vi, 8rem);
--space-section: clamp(5rem, 10vi, 8rem);
/* Radius */
--radius-xs: 0.125rem;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 1rem;
--radius-xl: 1.5rem;
--radius-lg: 0.875rem;
--radius-xl: 1.25rem;
--radius-2xl: 1.75rem;
/* Shadows */
--shadow-sm: 0 1px 3px oklch(0 0 0 / 0.3);
--shadow-md: 0 4px 12px oklch(0 0 0 / 0.4);
--shadow-lg: 0 8px 32px oklch(0 0 0 / 0.5);
--shadow-glow: 0 0 40px oklch(0.570 0.158 353.3 / 0.2);
--shadow-sm: 0 1px 3px oklch(0 0 0 / 0.4);
--shadow-md: 0 4px 16px oklch(0 0 0 / 0.5);
--shadow-lg: 0 12px 48px oklch(0 0 0 / 0.6);
--shadow-glow: 0 0 60px oklch(0.550 0.180 353.3 / 0.15);
--shadow-glow-strong: 0 0 80px oklch(0.550 0.180 353.3 / 0.25);
--shadow-inner: inset 0 1px 0 oklch(1 0 0 / 0.04);
/* Transitions */
--ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--duration-fast: 150ms;
--duration-normal: 300ms;
--duration-slow: 500ms;
--duration-slower: 800ms;
/* Z-index scale */
--z-base: 0;
--z-above: 10;
--z-dropdown: 100;
--z-sticky: 200;
--z-modal-backdrop: 300;
......@@ -79,7 +90,7 @@
--z-tooltip: 600;
/* Layout */
--container-max: 1280px;
--container-wide: 1440px;
--content-max: 75ch;
--container-max: 1200px;
--container-wide: 1400px;
--content-max: 65ch;
}
......@@ -2,6 +2,9 @@ document.addEventListener('DOMContentLoaded', () => {
initNav();
initReveal();
initMobileMenu();
initParallax();
initCountUp();
initSmoothHover();
});
function initNav() {
......@@ -12,12 +15,14 @@ function initNav() {
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(() => {
nav.classList.toggle('nav--scrolled', window.scrollY > 50);
nav.classList.toggle('nav--scrolled', window.scrollY > 30);
ticking = false;
});
ticking = true;
}
}, { passive: true });
if (window.scrollY > 30) nav.classList.add('nav--scrolled');
}
function initMobileMenu() {
......@@ -32,7 +37,7 @@ function initMobileMenu() {
});
links.addEventListener('click', (e) => {
if (e.target.classList.contains('nav__link')) {
if (e.target.classList.contains('nav__link') || e.target.classList.contains('nav__cta')) {
links.classList.remove('nav__links--open');
toggle.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
......@@ -41,7 +46,12 @@ function initMobileMenu() {
}
function initReveal() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
document.querySelectorAll('[data-reveal]').forEach(el => {
el.style.opacity = '1';
});
return;
}
const observer = new IntersectionObserver(
(entries) => {
......@@ -52,21 +62,127 @@ function initReveal() {
}
});
},
{ threshold: 0.1, rootMargin: '0px 0px -50px 0px' }
{ threshold: 0.08, rootMargin: '0px 0px -60px 0px' }
);
document.querySelectorAll('[data-reveal]').forEach((el) => {
document.querySelectorAll('[data-reveal]').forEach((el, i) => {
const delay = parseInt(el.dataset.reveal) || 0;
el.style.opacity = '0';
el.style.transform = 'translateY(24px)';
el.style.transition = `opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1)`;
const delay = el.dataset.reveal || '0';
el.style.transitionDelay = `${delay}ms`;
el.style.transform = 'translateY(32px)';
el.style.transition = `opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1) ${delay}ms, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1) ${delay}ms`;
observer.observe(el);
});
}
document.documentElement.addEventListener('animationend', () => {});
function initParallax() {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const heroVisual = document.querySelector('.hero__visual');
if (!heroVisual) return;
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(() => {
const scrolled = window.scrollY;
const rate = scrolled * 0.15;
if (scrolled < window.innerHeight) {
heroVisual.style.transform = `translateY(${rate}px)`;
}
ticking = false;
});
ticking = true;
}
}, { passive: true });
}
function initCountUp() {
const stats = document.querySelectorAll('.stat__value');
if (!stats.length) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
animateValue(entry.target);
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.5 }
);
stats.forEach(stat => observer.observe(stat));
}
function animateValue(el) {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const text = el.textContent.trim();
const hasPlus = text.startsWith('+');
const hasPercent = text.endsWith('%');
const numStr = text.replace(/[^0-9.]/g, '');
const target = parseFloat(numStr);
if (isNaN(target)) return;
const duration = 1500;
const start = performance.now();
function update(now) {
const elapsed = now - start;
const progress = Math.min(elapsed / duration, 1);
const eased = 1 - Math.pow(1 - progress, 4);
const current = Math.round(eased * target);
el.textContent = (hasPlus ? '+' : '') + current + (hasPercent ? '%' : '');
if (progress < 1) {
requestAnimationFrame(update);
}
}
el.textContent = (hasPlus ? '+' : '') + '0' + (hasPercent ? '%' : '');
requestAnimationFrame(update);
}
function initSmoothHover() {
const cards = document.querySelectorAll('.module-card, .feature-card, .pain-point');
cards.forEach(card => {
card.addEventListener('mouseenter', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
card.style.setProperty('--mouse-x', `${x}px`);
card.style.setProperty('--mouse-y', `${y}px`);
});
card.addEventListener('mousemove', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
card.style.setProperty('--mouse-x', `${x}px`);
card.style.setProperty('--mouse-y', `${y}px`);
});
});
}
// Inject styles
const style = document.createElement('style');
style.textContent = `.revealed { opacity: 1 !important; transform: translateY(0) !important; }`;
style.textContent = `
.revealed {
opacity: 1 !important;
transform: translateY(0) !important;
}
.module-card::before,
.feature-card::before,
.pain-point::before {
background: radial-gradient(
400px circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
oklch(0.550 0.180 353.3 / 0.04),
transparent 60%
) !important;
opacity: 1 !important;
}
`;
document.head.appendChild(style);
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