- Removed obsolete components including ContactSection, PopularServicesSection, RemoteSupportSection, SolutionsCarousel, and TrustSection to streamline the landing page. - Introduced new components such as TrustStrip and ServicesGrid for improved layout and functionality. - Enhanced global CSS with new line-height tokens and updated styles for better typography. - Updated PublicLandingLoadingView for consistent loading states across the landing page. - Added new landing services data structure to support the ServicesGrid component.
639 lines
14 KiB
CSS
639 lines
14 KiB
CSS
/**
|
|
* Design System Utilities
|
|
*
|
|
* Semantic component primitives using the consolidated color system.
|
|
* Layout, spacing, typography utilities come from Tailwind.
|
|
*/
|
|
|
|
/* ===== KEYFRAMES ===== */
|
|
|
|
@keyframes cp-fade-up {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(var(--cp-translate-lg));
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-fade-scale {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.95);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-slide-in-left {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(calc(var(--cp-translate-xl) * -1));
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-shimmer {
|
|
0% {
|
|
transform: translateX(-100%);
|
|
}
|
|
100% {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-toast-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(100%) scale(0.9);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0) scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-toast-exit {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateX(0) scale(1);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateX(100%) scale(0.9);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-shake {
|
|
0%,
|
|
100% {
|
|
transform: translateX(0);
|
|
}
|
|
20%,
|
|
60% {
|
|
transform: translateX(-4px);
|
|
}
|
|
40%,
|
|
80% {
|
|
transform: translateX(4px);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-activity-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateX(-8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-float {
|
|
0%,
|
|
100% {
|
|
transform: translateY(0px) rotate(0deg);
|
|
}
|
|
50% {
|
|
transform: translateY(-20px) rotate(2deg);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-float-slow {
|
|
0%,
|
|
100% {
|
|
transform: translateY(0px) rotate(0deg);
|
|
}
|
|
50% {
|
|
transform: translateY(-12px) rotate(-1deg);
|
|
}
|
|
}
|
|
|
|
@keyframes cp-pulse-glow {
|
|
0%,
|
|
100% {
|
|
box-shadow: 0 0 0 0 var(--primary);
|
|
}
|
|
50% {
|
|
box-shadow: 0 0 20px 4px color-mix(in oklch, var(--primary) 40%, transparent);
|
|
}
|
|
}
|
|
|
|
/* Legacy shimmer animation for compatibility */
|
|
@keyframes cp-skeleton-shimmer {
|
|
0% {
|
|
transform: translateX(-100%);
|
|
}
|
|
100% {
|
|
transform: translateX(100%);
|
|
}
|
|
}
|
|
|
|
/* ===== DISPLAY TYPOGRAPHY (Tailwind v4 @utility) ===== */
|
|
/* Only set font-size + letter-spacing. Font weight, line-height, and
|
|
font-family are explicit Tailwind classes at the call site so they
|
|
can be overridden without cascade conflicts. */
|
|
|
|
@utility text-display-xl {
|
|
font-size: var(--cp-text-display-xl);
|
|
letter-spacing: var(--cp-tracking-tight);
|
|
}
|
|
|
|
@utility text-display-lg {
|
|
font-size: var(--cp-text-display-lg);
|
|
letter-spacing: var(--cp-tracking-tight);
|
|
}
|
|
|
|
@utility text-display-md {
|
|
font-size: var(--cp-text-display-md);
|
|
letter-spacing: var(--cp-tracking-tight);
|
|
}
|
|
|
|
@utility text-display-sm {
|
|
font-size: var(--cp-text-display-sm);
|
|
letter-spacing: var(--cp-tracking-tight);
|
|
}
|
|
|
|
@layer utilities {
|
|
/* ===== PAGE ENTRANCE ANIMATIONS ===== */
|
|
.cp-animate-in {
|
|
animation: cp-fade-up var(--cp-duration-slow) var(--cp-ease-out) forwards;
|
|
}
|
|
|
|
.cp-animate-scale-in {
|
|
animation: cp-fade-scale var(--cp-duration-normal) var(--cp-ease-out) forwards;
|
|
}
|
|
|
|
.cp-animate-slide-left {
|
|
animation: cp-slide-in-left var(--cp-duration-slow) var(--cp-ease-out) forwards;
|
|
}
|
|
|
|
/* Staggered children animation */
|
|
.cp-stagger-children > * {
|
|
opacity: 0;
|
|
animation: cp-fade-up var(--cp-duration-slow) var(--cp-ease-out) forwards;
|
|
}
|
|
|
|
.cp-stagger-children > *:nth-child(1) {
|
|
animation-delay: var(--cp-stagger-1);
|
|
}
|
|
.cp-stagger-children > *:nth-child(2) {
|
|
animation-delay: var(--cp-stagger-2);
|
|
}
|
|
.cp-stagger-children > *:nth-child(3) {
|
|
animation-delay: var(--cp-stagger-3);
|
|
}
|
|
.cp-stagger-children > *:nth-child(4) {
|
|
animation-delay: var(--cp-stagger-4);
|
|
}
|
|
.cp-stagger-children > *:nth-child(5) {
|
|
animation-delay: var(--cp-stagger-5);
|
|
}
|
|
.cp-stagger-children > *:nth-child(n + 6) {
|
|
animation-delay: calc(var(--cp-stagger-5) + 50ms);
|
|
}
|
|
|
|
/* ===== CARD HOVER LIFT ===== */
|
|
.cp-card-hover-lift {
|
|
transition:
|
|
transform var(--cp-duration-normal) var(--cp-ease-out),
|
|
box-shadow var(--cp-duration-normal) var(--cp-ease-out);
|
|
}
|
|
|
|
.cp-card-hover-lift:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow:
|
|
0 10px 40px -10px rgb(0 0 0 / 0.15),
|
|
0 4px 6px -2px rgb(0 0 0 / 0.05);
|
|
}
|
|
|
|
.cp-card-hover-lift:active {
|
|
transform: translateY(0);
|
|
transition-duration: var(--cp-duration-fast);
|
|
}
|
|
|
|
/* ===== SKELETON SHIMMER ===== */
|
|
.cp-skeleton-shimmer {
|
|
position: relative;
|
|
overflow: hidden;
|
|
background: var(--cp-skeleton-base);
|
|
}
|
|
|
|
.cp-skeleton-shimmer::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(
|
|
90deg,
|
|
transparent 0%,
|
|
var(--cp-skeleton-shimmer) 50%,
|
|
transparent 100%
|
|
);
|
|
animation: cp-shimmer 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
/* ===== INPUT FOCUS ANIMATIONS ===== */
|
|
.cp-input-focus {
|
|
transition:
|
|
border-color var(--cp-duration-fast) var(--cp-ease-out),
|
|
box-shadow var(--cp-duration-fast) var(--cp-ease-out),
|
|
background-color var(--cp-duration-fast) var(--cp-ease-out);
|
|
}
|
|
|
|
.cp-input-focus:focus {
|
|
border-color: var(--primary);
|
|
box-shadow: 0 0 0 3px color-mix(in oklch, var(--primary) 15%, transparent);
|
|
}
|
|
|
|
.cp-input-error-shake {
|
|
animation: cp-shake var(--cp-duration-slow) var(--cp-ease-out);
|
|
}
|
|
|
|
/* ===== TOAST ANIMATIONS ===== */
|
|
.cp-toast-enter {
|
|
animation: cp-toast-enter var(--cp-duration-slow) var(--cp-ease-spring) forwards;
|
|
}
|
|
|
|
.cp-toast-exit {
|
|
animation: cp-toast-exit var(--cp-duration-normal) var(--cp-ease-in) forwards;
|
|
}
|
|
|
|
/* ===== ACTIVITY FEED ===== */
|
|
.cp-activity-item {
|
|
opacity: 0;
|
|
animation: cp-activity-enter var(--cp-duration-normal) var(--cp-ease-out) forwards;
|
|
}
|
|
|
|
.cp-activity-item:nth-child(1) {
|
|
animation-delay: 0ms;
|
|
}
|
|
.cp-activity-item:nth-child(2) {
|
|
animation-delay: 50ms;
|
|
}
|
|
.cp-activity-item:nth-child(3) {
|
|
animation-delay: 100ms;
|
|
}
|
|
.cp-activity-item:nth-child(4) {
|
|
animation-delay: 150ms;
|
|
}
|
|
.cp-activity-item:nth-child(5) {
|
|
animation-delay: 200ms;
|
|
}
|
|
|
|
/* ===== FLOAT ANIMATIONS ===== */
|
|
.cp-float {
|
|
animation: cp-float 6s ease-in-out infinite;
|
|
}
|
|
|
|
.cp-float-slow {
|
|
animation: cp-float-slow 8s ease-in-out infinite;
|
|
}
|
|
|
|
.cp-float-delayed {
|
|
animation: cp-float 6s ease-in-out infinite 2s;
|
|
}
|
|
|
|
/* ===== GLASS MORPHISM ===== */
|
|
.cp-glass {
|
|
background: var(--glass-bg);
|
|
backdrop-filter: blur(var(--glass-blur));
|
|
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
border: 1px solid var(--glass-border);
|
|
}
|
|
|
|
.cp-glass-strong {
|
|
background: var(--glass-bg-strong);
|
|
backdrop-filter: blur(var(--glass-blur-strong));
|
|
-webkit-backdrop-filter: blur(var(--glass-blur-strong));
|
|
border: 1px solid var(--glass-border);
|
|
}
|
|
|
|
.cp-glass-card {
|
|
background: var(--glass-bg);
|
|
backdrop-filter: blur(var(--glass-blur));
|
|
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
border: 1px solid var(--glass-border);
|
|
border-radius: var(--cp-card-radius);
|
|
box-shadow:
|
|
0 4px 24px -4px oklch(0 0 0 / 0.08),
|
|
inset 0 1px 0 oklch(1 0 0 / 0.1);
|
|
}
|
|
|
|
/* ===== GRADIENTS ===== */
|
|
.cp-gradient-primary {
|
|
background: var(--gradient-primary);
|
|
}
|
|
|
|
.cp-gradient-premium {
|
|
background: var(--gradient-premium);
|
|
}
|
|
|
|
.cp-gradient-subtle {
|
|
background: var(--gradient-subtle);
|
|
}
|
|
|
|
.cp-gradient-text {
|
|
background: var(--gradient-primary);
|
|
-webkit-background-clip: text;
|
|
background-clip: text;
|
|
color: transparent;
|
|
}
|
|
|
|
.cp-gradient-glow {
|
|
position: relative;
|
|
}
|
|
|
|
.cp-gradient-glow::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: -1px;
|
|
background: var(--gradient-primary);
|
|
border-radius: inherit;
|
|
z-index: -1;
|
|
opacity: 0;
|
|
filter: blur(12px);
|
|
transition: opacity var(--cp-duration-slow) ease;
|
|
}
|
|
|
|
.cp-gradient-glow:hover::before {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
/* ===== PREMIUM BUTTONS ===== */
|
|
.cp-btn-premium {
|
|
background: var(--gradient-primary);
|
|
color: var(--primary-foreground);
|
|
box-shadow: var(--shadow-primary-sm);
|
|
transition: all var(--cp-duration-normal) ease;
|
|
}
|
|
|
|
.cp-btn-premium:hover {
|
|
box-shadow: var(--shadow-primary-md);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.cp-btn-premium:active {
|
|
transform: translateY(0);
|
|
box-shadow: var(--shadow-primary-sm);
|
|
}
|
|
|
|
/* ===== GLOW EFFECTS ===== */
|
|
.cp-glow {
|
|
box-shadow: var(--shadow-primary-sm);
|
|
transition: box-shadow var(--cp-duration-slow) ease;
|
|
}
|
|
|
|
.cp-glow:hover {
|
|
box-shadow: var(--shadow-primary-lg);
|
|
}
|
|
|
|
.cp-glow-pulse {
|
|
animation: cp-pulse-glow 2s ease-in-out infinite;
|
|
}
|
|
|
|
/* ===== PREMIUM CARD VARIANTS ===== */
|
|
.cp-card-glass {
|
|
background: var(--glass-bg);
|
|
backdrop-filter: blur(var(--glass-blur));
|
|
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
border: 1px solid var(--glass-border);
|
|
border-radius: var(--cp-card-radius);
|
|
box-shadow:
|
|
0 4px 24px -4px oklch(0 0 0 / 0.06),
|
|
inset 0 1px 0 oklch(1 0 0 / 0.08);
|
|
}
|
|
|
|
.cp-card-gradient {
|
|
background: var(--gradient-subtle);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--cp-card-radius);
|
|
}
|
|
|
|
.cp-card-premium {
|
|
background: var(--card);
|
|
border: 1px solid color-mix(in oklch, var(--primary) 20%, transparent);
|
|
border-radius: var(--cp-card-radius);
|
|
box-shadow:
|
|
0 4px 24px -4px color-mix(in oklch, var(--primary) 8%, transparent),
|
|
inset 0 1px 0 oklch(1 0 0 / 0.05);
|
|
transition: all var(--cp-duration-normal) ease;
|
|
}
|
|
|
|
.cp-card-premium:hover {
|
|
border-color: color-mix(in oklch, var(--primary) 40%, transparent);
|
|
box-shadow:
|
|
0 8px 32px -8px color-mix(in oklch, var(--primary) 15%, transparent),
|
|
inset 0 1px 0 oklch(1 0 0 / 0.05);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
/* ===== GRADIENT BORDER ===== */
|
|
.cp-gradient-border {
|
|
position: relative;
|
|
}
|
|
|
|
.cp-gradient-border::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
padding: 1px;
|
|
border-radius: inherit;
|
|
background: var(--gradient-primary);
|
|
-webkit-mask:
|
|
linear-gradient(#fff 0 0) content-box,
|
|
linear-gradient(#fff 0 0);
|
|
-webkit-mask-composite: xor;
|
|
mask-composite: exclude;
|
|
opacity: 0;
|
|
transition: opacity var(--cp-duration-slow) ease;
|
|
}
|
|
|
|
.cp-gradient-border:hover::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* ===== CARD (legacy) ===== */
|
|
.cp-card {
|
|
background: var(--card);
|
|
color: var(--card-foreground);
|
|
border: 1px solid color-mix(in oklch, var(--border) 60%, transparent);
|
|
border-radius: var(--cp-card-radius);
|
|
box-shadow: var(--cp-card-shadow);
|
|
padding: var(--cp-card-padding);
|
|
transition:
|
|
box-shadow var(--cp-duration-normal) ease,
|
|
border-color var(--cp-duration-normal) ease;
|
|
}
|
|
|
|
.cp-card:hover {
|
|
box-shadow: var(--cp-card-shadow-lg);
|
|
border-color: var(--border);
|
|
}
|
|
|
|
.cp-card-sm {
|
|
padding: var(--cp-card-padding-sm);
|
|
}
|
|
|
|
.cp-card-lg {
|
|
border-radius: var(--cp-card-radius-lg);
|
|
box-shadow: var(--cp-card-shadow-lg);
|
|
}
|
|
|
|
.cp-card-interactive {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cp-card-interactive:hover {
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.cp-card-interactive:active {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
/* ===== BADGE ===== */
|
|
.cp-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--cp-space-1);
|
|
border-radius: var(--cp-badge-radius);
|
|
padding: var(--cp-badge-padding-y) var(--cp-badge-padding-x);
|
|
font-size: var(--cp-badge-font-size);
|
|
font-weight: var(--cp-badge-font-weight);
|
|
line-height: 1;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
/* Badge variants - using 5 semantic colors */
|
|
.cp-badge-primary {
|
|
background: var(--primary);
|
|
color: var(--primary-foreground);
|
|
}
|
|
|
|
.cp-badge-secondary {
|
|
background: var(--secondary);
|
|
color: var(--secondary-foreground);
|
|
}
|
|
|
|
.cp-badge-success {
|
|
background: var(--success);
|
|
color: var(--success-foreground);
|
|
}
|
|
|
|
.cp-badge-info {
|
|
background: var(--info);
|
|
color: var(--info-foreground);
|
|
}
|
|
|
|
.cp-badge-warning {
|
|
background: var(--warning);
|
|
color: var(--warning-foreground);
|
|
}
|
|
|
|
.cp-badge-danger {
|
|
background: var(--danger);
|
|
color: var(--danger-foreground);
|
|
}
|
|
|
|
.cp-badge-neutral {
|
|
background: var(--neutral);
|
|
color: var(--neutral-foreground);
|
|
}
|
|
|
|
/* Soft badge variants (light bg, dark text) */
|
|
.cp-badge-soft-success {
|
|
background: var(--success-soft);
|
|
color: var(--success);
|
|
}
|
|
|
|
.cp-badge-soft-info {
|
|
background: var(--info-soft);
|
|
color: var(--info);
|
|
}
|
|
|
|
.cp-badge-soft-warning {
|
|
background: var(--warning-soft);
|
|
color: var(--warning);
|
|
}
|
|
|
|
.cp-badge-soft-danger {
|
|
background: var(--danger-soft);
|
|
color: var(--danger);
|
|
}
|
|
|
|
.cp-badge-soft-neutral {
|
|
background: var(--neutral-soft);
|
|
color: var(--neutral);
|
|
}
|
|
|
|
.cp-badge-outline {
|
|
background: transparent;
|
|
border: 1px solid currentColor;
|
|
}
|
|
|
|
/* ===== SKELETON (Loading state) ===== */
|
|
.cp-skeleton {
|
|
background: var(--cp-skeleton-base);
|
|
border-radius: var(--cp-radius-md);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.cp-skeleton::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
background: linear-gradient(90deg, transparent, var(--cp-skeleton-shimmer), transparent);
|
|
animation: cp-skeleton-shimmer 2s infinite;
|
|
}
|
|
|
|
/* ===== FOCUS RING ===== */
|
|
.cp-focus-ring {
|
|
outline: var(--cp-focus-ring);
|
|
outline-offset: var(--cp-focus-ring-offset);
|
|
}
|
|
|
|
.cp-focus-ring-visible:focus-visible {
|
|
outline: var(--cp-focus-ring);
|
|
outline-offset: var(--cp-focus-ring-offset);
|
|
}
|
|
|
|
/* ===== SCROLLBAR ===== */
|
|
.scrollbar-hide {
|
|
-ms-overflow-style: none; /* IE and Edge */
|
|
scrollbar-width: none; /* Firefox */
|
|
}
|
|
|
|
.scrollbar-hide::-webkit-scrollbar {
|
|
display: none; /* Chrome, Safari, Opera */
|
|
}
|
|
|
|
/* ===== ACCESSIBILITY: REDUCED MOTION ===== */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.cp-animate-in,
|
|
.cp-animate-scale-in,
|
|
.cp-animate-slide-left,
|
|
.cp-stagger-children > *,
|
|
.cp-card-hover-lift,
|
|
.cp-toast-enter,
|
|
.cp-toast-exit,
|
|
.cp-activity-item,
|
|
.cp-float,
|
|
.cp-float-slow,
|
|
.cp-float-delayed,
|
|
.cp-glow-pulse {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
opacity: 1 !important;
|
|
}
|
|
}
|
|
}
|