cellex-web / src /app /globals.css
eeshaAI
feat: Migrate frontend from static HTML to Next.js 16 App Router
a09d2a4
Raw
History Blame Contribute Delete
36.3 kB
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}
/* ============================================================
Cellex Design System — Instagram-inspired
Social commerce: IG's clean white UI + commerce CTAs.
- System font stack (matches IG exactly)
- Pure white bg / pure black text
- #f5f5f5 hover, #dbdbdb borders, #8e8e8e secondary text
- Square media in feed (1:1, full-bleed within card)
- Compact action bar (24px icons, no labels)
============================================================ */
:root {
--background: #050508;
--foreground: #ffffff;
--card: rgba(255, 255, 255, 0.07);
--card-foreground: #000000;
--popover: #ffffff;
--popover-foreground: #000000;
--primary: #000000;
--primary-hover: #262626;
--primary-foreground: #ffffff;
--secondary: rgba(255, 255, 255, 0.05);
--secondary-foreground: #000000;
--muted: #f5f5f5;
--muted-foreground: #8e8e8e;
--accent: #efefef;
--accent-foreground: #000000;
--destructive: #ed4956; /* IG red */
--destructive-foreground: #ffffff;
--border: rgba(255, 255, 255, 0.08);
--input: rgba(255, 255, 255, 0.1);
--ring: #000000;
--chart-1: #000000;
--chart-2: #333333;
--chart-3: #666666;
--chart-4: #999999;
--chart-5: #cccccc;
--radius: 0.5rem;
--sidebar: #000000;
--sidebar-foreground: #e2e8f0;
--sidebar-primary: #ffffff;
--sidebar-primary-foreground: #000000;
--sidebar-accent: #1a1a1a;
--sidebar-accent-foreground: #e2e8f0;
--sidebar-border: #1a1a1a;
--sidebar-ring: #ffffff;
/* IG-style font stack */
--font-ig: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.dark {
--background: #050508;
--foreground: #ffffff;
--card: rgba(255, 255, 255, 0.07);
--card-foreground: #e2e8f0;
--popover: #1e293b;
--popover-foreground: #e2e8f0;
--primary: #ffffff;
--primary-foreground: #000000;
--secondary: #334155;
--secondary-foreground: #e2e8f0;
--muted: #334155;
--muted-foreground: #94a3b8;
--accent: #1e293b;
--accent-foreground: #ffffff;
--destructive: #ef4444;
--destructive-foreground: #ffffff;
--border: rgba(255, 255, 255, 0.08);
--input: #334155;
--ring: #ffffff;
}
* {
border-color: rgba(255, 255, 255, 0.08);
}
html {
font-size: 16px;
scroll-behavior: smooth;
}
body {
background-color: var(--background);
color: var(--foreground);
font-size: 16px;
line-height: 1.5;
font-family: var(--font-ig);
font-feature-settings: "rlig" 1, "calt" 1;
}
h1 { font-size: 1.5rem; line-height: 1.3; }
h2 { font-size: 1.25rem; line-height: 1.35; }
h3 { font-size: 1.125rem; line-height: 1.4; }
/* Brand — indigo gradient for dark theme */
.brand-gradient {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
}
.brand-text {
color: #ffffff;
}
/* Price — white bold (dark theme) */
.price {
color: #ffffff;
font-weight: 700;
}
/* Glow — subtle dark shadow */
.glow {
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
}
.glow-hover:hover {
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}
/* Hide scrollbar */
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
/* Sale badge — indigo */
.sale-badge {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
color: #ffffff;
font-weight: 700;
border-radius: 4px;
padding: 2px 6px;
font-size: 12px;
line-height: 1.2;
}
/* Bestseller badge — gold */
.bestseller-badge {
background: linear-gradient(135deg, #b8860b 0%, #8b6914 100%);
color: #fff;
font-weight: 700;
border-radius: 4px;
padding: 2px 6px;
font-size: 12px;
}
/* Buy Now button — indigo gradient */
.btn-buy-now {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
color: #ffffff;
font-weight: 700;
font-size: 16px;
border-radius: 999px;
padding: 12px 24px;
border: none;
cursor: pointer;
transition: all 0.2s ease;
min-height: 44px;
box-shadow: 0 4px 16px rgba(99, 102, 241, 0.3);
}
.btn-buy-now:hover { background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%); transform: translateY(-1px); }
.btn-buy-now:active { transform: translateY(0); }
/* Urgency — indigo */
.urgency {
color: #a5b4fc;
font-weight: 700;
}
/* Input fields — 16px to prevent iOS zoom */
input, textarea, select {
font-size: 16px;
}
button {
font-size: 16px;
}
/* ============================================================
ANIMATIONS
============================================================ */
/* Fade in */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Slide up */
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Slide in from left */
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); }
}
/* Scale in */
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
/* Shimmer (for skeletons) */
@keyframes shimmer {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
/* Page transition */
@keyframes pageEnter {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
/* Utility classes */
.animate-fade-in {
animation: fadeIn 0.4s ease-out forwards;
}
.animate-slide-up {
animation: slideUp 0.4s ease-out forwards;
}
.animate-slide-in-left {
animation: slideInLeft 0.3s ease-out forwards;
}
.animate-scale-in {
animation: scaleIn 0.3s ease-out forwards;
}
.animate-page-enter {
animation: pageEnter 0.3s ease-out forwards;
}
/* Staggered delays */
.delay-0 { animation-delay: 0ms; }
.delay-50 { animation-delay: 50ms; }
.delay-100 { animation-delay: 100ms; }
.delay-150 { animation-delay: 150ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
.delay-400 { animation-delay: 400ms; }
.delay-500 { animation-delay: 500ms; }
/* Skeleton shimmer */
.skeleton {
background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.08) 50%, rgba(255,255,255,0.04) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
/* Shimmer utility — used by loading.tsx skeleton */
.shimmer {
background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.08) 50%, rgba(255,255,255,0.04) 100%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
/* Hover lift effect */
.hover-lift {
transition: all 0.2s ease;
}
.hover-lift:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
/* Smooth card transitions */
.card-transition {
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Button transitions */
button, a {
transition: all 0.15s ease;
}
/* Image zoom on hover */
.img-zoom {
overflow: hidden;
}
.img-zoom img {
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.img-zoom:hover img {
transform: scale(1.08);
}
/* Page transition overlay */
.page-transition {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #050508;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
animation: fadeIn 0.2s ease-out;
}
.page-transition-exit {
animation: fadeIn 0.2s ease-out reverse;
}
/* Loading dots */
.loading-dots span {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #6366f1;
margin: 0 3px;
animation: loadingDots 1.4s infinite ease-in-out;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
@keyframes loadingDots {
0%, 80%, 100% { transform: scale(0); opacity: 0.5; }
40% { transform: scale(1); opacity: 1; }
}
/* Smooth pulse for live badges */
@keyframes smoothPulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.smooth-pulse {
animation: smoothPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
/* ============================================================
MOBILE WEBVIEW SIZING FIXES (Capacitor)
Fixes the "page appears zoomed in on first paint" bug by:
1. Pinning html/body width to 100vw (no horizontal overflow)
2. Disabling iOS text auto-inflation
3. Disabling tap-highlight + long-press callout (native feel)
4. Respecting the notch / dynamic island via env(safe-area-inset-*)
============================================================ */
html, body {
width: 100%;
max-width: 100vw;
overflow-x: hidden;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
}
/* Safe-area insets: applied on the body so every page gets them automatically.
NOTE: padding-top is NOT applied here because the fixed .ig-topbar handles
the top inset itself (positioned at top: env(safe-area-inset-top)). If we
added body padding-top too, we'd get double spacing on pages with a topbar. */
body {
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
/* The bottom mobile-nav should sit ABOVE the home-indicator bar on iPhone X+. */
nav.fixed.bottom-0 {
padding-bottom: env(safe-area-inset-bottom);
}
/* While the page is being dragged via swipe-back, add a subtle drop-shadow
to sell the "card sliding over the previous page" effect (iOS-like). */
.page-shell.is-dragging {
box-shadow: -8px 0 24px rgba(0, 0, 0, 0.18);
}
/* ============================================================
NAVIGATION (standard Next.js — no iOS stack)
============================================================ */
html, body {
overscroll-behavior-x: none;
-webkit-font-smoothing: antialiased;
}
/* ============================================================
INSTAGRAM-STYLE UTILITIES (applied across the app)
============================================================ */
/* IG-style container — centers content, max 470px on mobile (matches IG feed width) */
.ig-container {
max-width: 470px;
margin: 0 auto;
width: 100%;
}
/* IG-style top bar — FIXED at top, white, 1px bottom border, compact height.
Uses position: fixed so it stays pinned during scroll (matches IG mobile web).
Positioned at top: env(safe-area-inset-top) so it sits BELOW the iPhone notch.
Pages that use .ig-topbar have pt-[54px] added to their root div by the
add_topbar_offset.py script. The offset is augmented with safe-area-inset-top
via the .ig-topbar-offset class (use that instead of pt-[54px] for pages
that need to account for the notch). */
.ig-topbar {
position: fixed;
top: env(safe-area-inset-top);
left: 0;
right: 0;
z-index: 50;
background: rgba(5, 5, 8, 0.6) !important;
backdrop-filter: blur(25px) saturate(180%) !important;
-webkit-backdrop-filter: blur(25px) saturate(180%) !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
height: 54px;
display: flex;
align-items: center;
padding: 0 12px;
max-width: 470px;
margin: 0 auto;
}
/* On desktop (>=768px), allow the top bar to span wider but still centered */
@media (min-width: 768px) {
.ig-topbar {
max-width: 935px;
}
}
/* Helper class — adds top padding equal to the fixed topbar height + notch.
Applied automatically to page root divs by add_topbar_offset.py. */
.ig-topbar-offset {
padding-top: calc(54px + env(safe-area-inset-top));
}
/* IG logo — bold serif-style wordmark */
.ig-logo {
font-family: var(--font-ig);
font-weight: 800;
font-size: 22px;
letter-spacing: -0.5px;
color: #ffffff;
}
/* IG-style stories ring — gradient border around avatar */
.ig-story-ring {
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
padding: 2px;
border-radius: 50%;
}
/* IG-style avatar — circular, object-cover */
.ig-avatar-sm { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.ig-avatar-md { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; }
.ig-avatar-lg { width: 77px; height: 77px; border-radius: 50%; object-fit: cover; }
/* IG-style action bar — 24px icons, no labels, tight spacing */
.ig-action-bar {
display: flex;
align-items: center;
gap: 16px;
padding: 8px 12px;
}
.ig-action-bar button {
background: transparent;
border: none;
padding: 4px;
cursor: pointer;
color: #ffffff;
}
.ig-action-bar button:hover {
color: #cbd5e1;
}
/* IG-style icon button — used in top bar */
.ig-icon-btn {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
cursor: pointer;
color: #ffffff;
border-radius: 50%;
transition: background 0.15s ease;
}
.ig-icon-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
/* IG-style feed card — kept for backwards compat. New feed cards use
.ig-card (rounded iOS-style card with soft shadow). */
.ig-feed-card {
background: rgba(255, 255, 255, 0.04);
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
/* iOS-style rounded card — used for feed posts, suggested sellers,
live auctions, shorts and any self-contained content block.
- Dark glass background (the body has a subtle gradient so cards "float")
- 24px radius (matches iOS large corner radius)
- overflow: hidden so media conforms to the rounded corners
- Soft shadow for depth without being heavy */
.ig-card {
background: rgba(255, 255, 255, 0.06);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 24px;
overflow: hidden;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
color: #ffffff;
}
.dark .ig-card {
background: rgba(255, 255, 255, 0.06);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
}
/* Spacing helper — adds 12px horizontal margins + 16px bottom margin
so cards don't touch screen edges and are physically separated. */
.ig-card-spaced {
margin-left: 12px;
margin-right: 12px;
margin-bottom: 24px;
}
/* Cart item card — slightly smaller radius (20px) than feed cards,
with the same soft shadow. */
.ig-cart-card {
background: rgba(255, 255, 255, 0.06);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px;
overflow: hidden;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
color: #ffffff;
}
.dark .ig-cart-card {
background: rgba(255, 255, 255, 0.06);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
}
/* IG-style media — square, full-bleed */
.ig-media {
width: 100%;
aspect-ratio: 1 / 1;
background: rgba(255, 255, 255, 0.04);
position: relative;
overflow: hidden;
}
.ig-media img,
.ig-media video {
width: 100%;
height: 100%;
object-fit: cover;
}
/* IG-style likes count — bold, no label */
.ig-likes {
font-weight: 600;
font-size: 14px;
color: #ffffff;
padding: 0 12px 4px;
}
/* IG-style caption — bold username + text */
.ig-caption {
font-size: 14px;
color: #ffffff;
padding: 0 12px 8px;
line-height: 1.4;
}
.ig-caption .username {
font-weight: 600;
margin-right: 6px;
}
/* IG-style timestamp — uppercase, small, gray */
.ig-timestamp {
font-size: 10px;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 0.4px;
padding: 0 12px 12px;
}
/* IG-style "View all comments" link */
.ig-comments-link {
font-size: 14px;
color: #94a3b8;
padding: 0 12px 4px;
display: inline-block;
cursor: pointer;
}
.ig-comments-link:hover {
color: #cbd5e1;
}
/* Bottom nav — now a floating glass island (WhatsApp Liquid Glass style).
The actual styling is in the .glass-nav class. This is kept for backward
compatibility but the mobile-nav component now uses .glass-nav directly. */
.ig-bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 60;
height: 0px;
pointer-events: none;
}
/* IG-style profile header — 77px avatar + stats row */
.ig-profile-header {
display: flex;
align-items: center;
gap: 24px;
padding: 16px;
}
.ig-profile-stats {
display: flex;
gap: 20px;
flex: 1;
}
.ig-profile-stat {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}
.ig-profile-stat .num {
font-weight: 600;
font-size: 16px;
color: #ffffff;
}
.ig-profile-stat .label {
font-size: 12px;
color: #94a3b8;
}
/* IG-style post grid — 3 columns, no gaps */
.ig-post-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
background: rgba(255, 255, 255, 0.06);
border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.ig-post-grid > * {
aspect-ratio: 1 / 1;
background: rgba(255, 255, 255, 0.02);
overflow: hidden;
}
.ig-post-grid img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* IG-style tab bar under profile header */
.ig-tab-bar {
display: flex;
border-top: 1px solid rgba(255, 255, 255, 0.08);
height: 44px;
}
.ig-tab {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
cursor: pointer;
color: #94a3b8;
border-top: 1px solid transparent;
margin-top: -1px;
}
.ig-tab.active {
color: #ffffff;
border-top-color: #6366f1;
}
/* IG-style button — outlined (Edit Profile style) */
.ig-btn-outline {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.12);
color: #ffffff;
font-weight: 600;
font-size: 14px;
padding: 6px 16px;
border-radius: 6px;
cursor: pointer;
transition: background 0.15s ease;
}
.ig-btn-outline:hover {
background: rgba(255, 255, 255, 0.1);
}
/* IG-style primary button — indigo */
.ig-btn-primary {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
border: none;
color: #ffffff;
font-weight: 600;
font-size: 14px;
padding: 6px 24px;
border-radius: 6px;
cursor: pointer;
transition: background 0.15s ease;
box-shadow: 0 2px 12px rgba(99, 102, 241, 0.3);
}
.ig-btn-primary:hover {
background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);
}
.ig-btn-primary.following {
background: rgba(255, 255, 255, 0.08);
color: #ffffff;
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: none;
}
.ig-btn-primary.following:hover {
background: rgba(255, 255, 255, 0.12);
}
/* IG-style search input — glass pill, no border */
.ig-search-input {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 8px;
padding: 8px 16px;
font-size: 14px;
color: #ffffff;
width: 100%;
}
.ig-search-input:focus {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(99, 102, 241, 0.5);
outline: none;
}
.ig-search-input::placeholder {
color: #64748b;
}
/* Hide elements at IG breakpoints (desktop sidebar shows at >=768px) */
@media (min-width: 768px) {
.ig-bottom-nav, .glass-nav { display: none !important; }
}
/* ============================================================
VISUAL LIVENESS — animations + effects
These add motion and visual interest without being distracting.
============================================================ */
/* Scroll-triggered fade-in + slide-up.
Apply .reveal to any element; it starts invisible and animates in
when the .reveal-visible class is added (via IntersectionObserver). */
.reveal {
opacity: 0;
transform: translateY(16px);
transition: opacity 0.5s ease-out, transform 0.5s ease-out;
will-change: opacity, transform;
}
.reveal.reveal-visible {
opacity: 1;
transform: translateY(0);
}
/* IG gradient text — for the Cellex wordmark on special occasions */
.ig-gradient-text {
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* IG gradient button — for primary CTAs that need extra pop */
.ig-gradient-btn {
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
color: #ffffff;
font-weight: 600;
border: none;
border-radius: 8px;
padding: 8px 20px;
cursor: pointer;
transition: transform 0.15s ease, box-shadow 0.15s ease;
background-size: 150% 150%;
background-position: 0% 50%;
}
.ig-gradient-btn:hover {
background-position: 100% 50%;
box-shadow: 0 4px 12px rgba(220, 39, 67, 0.3);
}
.ig-gradient-btn:active {
transform: scale(0.97);
}
/* Image hover zoom — subtle scale-up on product images */
.ig-img-zoom {
overflow: hidden;
}
.ig-img-zoom img {
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.ig-img-zoom:hover img {
transform: scale(1.04);
}
/* Tap feedback — scale down on active (mobile) */
.ig-tap {
transition: transform 0.1s ease;
}
.ig-tap:active {
transform: scale(0.95);
}
/* Pulse glow — for the LIVE badge */
@keyframes pulseGlow {
0%, 100% { box-shadow: 0 0 0 0 rgba(237, 73, 86, 0.7); }
50% { box-shadow: 0 0 0 8px rgba(237, 73, 86, 0); }
}
.ig-pulse-glow {
animation: pulseGlow 2s infinite;
}
/* Shimmer — for the logo and loading states */
@keyframes shimmerMove {
0% { background-position: -200% 0; }
100% { background-position: 200% 0; }
}
.ig-shimmer {
background: linear-gradient(90deg, #6366f1 0%, #a5b4fc 50%, #6366f1 100%);
background-size: 200% 100%;
animation: shimmerMove 3s linear infinite;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* Bounce-in — for the suggested sellers cards */
@keyframes bounceIn {
0% { opacity: 0; transform: scale(0.8) translateY(10px); }
60% { opacity: 1; transform: scale(1.02) translateY(-2px); }
100% { opacity: 1; transform: scale(1) translateY(0); }
}
.ig-bounce-in {
animation: bounceIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
/* Heart burst — scale + fade for the like animation */
@keyframes heartBurst {
0% { transform: scale(1); }
30% { transform: scale(1.35); }
60% { transform: scale(0.95); }
100% { transform: scale(1); }
}
.ig-heart-burst {
animation: heartBurst 0.4s ease-out;
}
/* Subtle gradient background — applied to the homepage hero area */
.ig-hero-bg {
background: linear-gradient(180deg, rgba(99, 102, 241, 0.05) 0%, rgba(5, 5, 8, 0) 100%);
}
/* Floating animation — for the LIVE indicator dot */
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-2px); }
}
.ig-float {
animation: float 2s ease-in-out infinite;
}
/* Skeleton with IG gradient shimmer */
.ig-skeleton {
background: linear-gradient(90deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.08) 50%, rgba(255,255,255,0.04) 100%);
background-size: 200% 100%;
animation: shimmerMove 1.5s infinite;
border-radius: 4px;
}
/* Slide-in from right — for the suggested sellers carousel */
@keyframes slideInRight {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
.ig-slide-in-right {
animation: slideInRight 0.4s ease-out forwards;
}
/* Gradient border — for featured seller cards */
.ig-gradient-border {
position: relative;
background: rgba(255, 255, 255, 0.06);
border-radius: 12px;
}
.ig-gradient-border::before {
content: '';
position: absolute;
inset: -2px;
border-radius: 14px;
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
z-index: -1;
}
/* ============================================================
LIQUID GLASS — WhatsApp-style glassmorphism design system
Applied across: bottom nav, topbar, cards, modals, overlays
============================================================ */
/* ============================================================
LIQUID GLASS — WhatsApp iOS glassmorphism (exact specs)
Light: #FFFFFF 70% + #FFFFFF 45% border + 6% shadow, 24px blur
Dark: #121212 75% + #FFFFFF 12% border + 30% shadow, 16px blur
Engine: backdrop-blur(25px) saturate(120%)
============================================================ */
/* Base glass container */
.glass {
background: rgba(255, 255, 255, 0.06);
backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease-in-out;
}
.dark .glass {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.30);
}
/* Glass topbar — dark glass with blur */
.glass-topbar {
background: rgba(5, 5, 8, 0.6) !important;
backdrop-filter: blur(25px) saturate(180%) !important;
-webkit-backdrop-filter: blur(25px) saturate(180%) !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
}
.dark .glass-topbar {
background: rgba(5, 5, 8, 0.6) !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
}
/* Glass bottom nav — floating island */
.glass-nav {
background: rgba(15, 15, 25, 0.7);
backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 32px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease-in-out;
}
.dark .glass-nav {
background: rgba(15, 15, 25, 0.7);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
/* Active tab indicator */
.glass-active-pill {
background: rgba(0, 0, 0, 0.08);
border-radius: 16px;
transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.dark .glass-active-pill {
background: rgba(255, 255, 255, 0.12);
}
/* Glass card */
.glass-card {
background: rgba(255, 255, 255, 0.06);
backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.dark .glass-card {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.30);
}
/* Glass modal/sheet */
.glass-modal {
background: rgba(15, 15, 25, 0.85);
backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.dark .glass-modal {
background: rgba(15, 15, 25, 0.85);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.30);
}
/* Glass input */
.glass-input {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.dark .glass-input {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
}
/* Glass section — for content blocks, list sections */
.glass-section {
background: rgba(255, 255, 255, 0.04);
backdrop-filter: blur(15px) saturate(180%);
-webkit-backdrop-filter: blur(15px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.dark .glass-section {
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.08);
}
/* Spring animation for active tab transitions */
@keyframes glassPillSpring {
0% { transform: scale(0.8); opacity: 0; }
60% { transform: scale(1.05); opacity: 1; }
100% { transform: scale(1); opacity: 1; }
}
.glass-pill-enter {
animation: glassPillSpring 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
/* Subtle page background gradient for glass to look good */
body {
background: linear-gradient(180deg, #050508 0%, #0a0a14 50%, #050508 100%) !important;
min-height: 100vh;
}
.dark body {
background: linear-gradient(180deg, #050508 0%, #0a0a14 50%, #050508 100%) !important;
}
/* ============================================================
LIQUID GLASS — High-fidelity glassmorphism for dark smoke bg
============================================================ */
.liquid-glass {
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.07) 0%,
rgba(255, 255, 255, 0.02) 40%,
rgba(255, 255, 255, 0.05) 100%
);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
inset 0 1px 1px rgba(255, 255, 255, 0.2),
inset 0 -10px 20px rgba(255, 255, 255, 0.02),
0 8px 32px 0 rgba(0, 0, 0, 0.37);
}
.liquid-fluid {
background: linear-gradient(180deg, rgba(56, 189, 248, 0.3) 0%, rgba(59, 130, 246, 0.1) 100%);
backdrop-filter: blur(8px);
box-shadow:
inset 0 4px 6px rgba(255, 255, 255, 0.15),
0 4px 15px rgba(59, 130, 246, 0.2);
}
/* Accessibility: Focus states for keyboard navigation */
button:focus-visible,
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 2px solid rgba(56, 189, 248, 0.6);
outline-offset: 2px;
border-radius: 4px;
}
/* Accessibility: Better color contrast on dark bg */
.ig-timestamp {
color: #94a3b8 !important;
}
/* Scroll behavior: instant on mobile for performance */
@media (max-width: 768px) {
html {
scroll-behavior: auto !important;
}
}
/* ============================================================
FUTURISTIC DESIGN SYSTEM — Social E-Commerce
Unified across every page. Dark smoke bg + indigo accents
+ glassmorphism + smooth animations.
============================================================ */
/* --- Typography --- */
.text-display { font-size: 2rem; line-height: 1.2; font-weight: 800; letter-spacing: -0.02em; }
.text-headline { font-size: 1.5rem; line-height: 1.3; font-weight: 700; letter-spacing: -0.01em; }
.text-title { font-size: 1.125rem; line-height: 1.4; font-weight: 600; }
.text-body-lg { font-size: 1rem; line-height: 1.5; }
.text-body { font-size: 0.875rem; line-height: 1.5; }
.text-caption { font-size: 0.75rem; line-height: 1.4; }
.text-micro { font-size: 0.625rem; line-height: 1.3; }
/* --- Glass Cards (unified) --- */
.fx-card {
background: rgba(255, 255, 255, 0.06);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 20px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
color: #ffffff;
transition: all 0.3s ease;
}
.fx-card:hover {
border-color: rgba(99, 102, 241, 0.3);
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
}
/* --- Glass Topbar --- */
.fx-topbar {
background: rgba(5, 5, 8, 0.6) !important;
backdrop-filter: blur(20px) saturate(180%) !important;
-webkit-backdrop-filter: blur(20px) saturate(180%) !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
}
/* --- Glass Nav --- */
.fx-nav {
background: rgba(15, 15, 25, 0.7) !important;
backdrop-filter: blur(25px) saturate(180%) !important;
-webkit-backdrop-filter: blur(25px) saturate(180%) !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3) !important;
}
/* --- Buttons --- */
.fx-btn-primary {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
color: #ffffff;
font-weight: 600;
border-radius: 9999px;
padding: 12px 24px;
border: none;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 16px rgba(99, 102, 241, 0.3);
}
.fx-btn-primary:hover {
background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);
box-shadow: 0 6px 24px rgba(99, 102, 241, 0.4);
transform: translateY(-1px);
}
.fx-btn-primary:active { transform: translateY(0); }
.fx-btn-ghost {
background: rgba(255, 255, 255, 0.05);
color: #ffffff;
font-weight: 600;
border-radius: 9999px;
padding: 12px 24px;
border: 1px solid rgba(255, 255, 255, 0.1);
cursor: pointer;
transition: all 0.3s ease;
}
.fx-btn-ghost:hover {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
}
/* --- Inputs --- */
.fx-input {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 14px;
color: #ffffff;
padding: 12px 16px;
font-size: 14px;
transition: all 0.3s ease;
}
.fx-input:focus {
background: rgba(255, 255, 255, 0.08);
border-color: rgba(99, 102, 241, 0.5);
outline: none;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}
.fx-input::placeholder { color: #64748b; }
/* --- Pills / Tags --- */
.fx-pill {
background: rgba(255, 255, 255, 0.06);
color: #cbd5e1;
font-size: 13px;
font-weight: 600;
padding: 6px 14px;
border-radius: 9999px;
border: 1px solid rgba(255, 255, 255, 0.06);
transition: all 0.3s ease;
cursor: pointer;
}
.fx-pill:hover {
background: rgba(255, 255, 255, 0.1);
color: #ffffff;
}
.fx-pill.active {
background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
color: #ffffff;
border-color: transparent;
box-shadow: 0 2px 12px rgba(99, 102, 241, 0.3);
}
/* --- Section Headers --- */
.fx-section-title {
font-size: 14px;
font-weight: 700;
color: #ffffff;
letter-spacing: 0.02em;
display: flex;
align-items: center;
gap: 8px;
}
/* --- Links --- */
.fx-link {
color: #818cf8;
font-weight: 600;
transition: color 0.2s ease;
}
.fx-link:hover { color: #a5b4fc; }
/* --- Price --- */
.fx-price {
font-weight: 800;
font-size: 18px;
color: #ffffff;
letter-spacing: -0.01em;
}
/* --- Badges --- */
.fx-badge {
background: rgba(99, 102, 241, 0.15);
color: #a5b4fc;
font-size: 10px;
font-weight: 700;
padding: 4px 10px;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.fx-badge-red {
background: rgba(239, 68, 68, 0.15);
color: #fca5a5;
}
/* --- Dividers --- */
.fx-divider {
height: 1px;
background: rgba(255, 255, 255, 0.06);
border: none;
}
/* --- Animations --- */
@keyframes fx-fade-in {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
.fx-fade-in { animation: fx-fade-in 0.4s ease-out forwards; }
@keyframes fx-glow {
0%, 100% { box-shadow: 0 0 20px rgba(99, 102, 241, 0.1); }
50% { box-shadow: 0 0 40px rgba(99, 102, 241, 0.2); }
}
.fx-glow { animation: fx-glow 3s ease-in-out infinite; }
/* --- Scrollbar --- */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); }