Website / CustomCursor.css
Gokul08r's picture
Upload 31 files
e927672 verified
Raw
History Blame Contribute Delete
12 kB
/* ═══════════════════════════════════════════════════════════════════════════
CustomCursor.css β€” QUANTUM THEME-REACTIVE v5.0
PASTE THIS β†’ src/components/CustomCursor.css
How theme reactivity works:
β€’ All cursor colors use CSS variables (--cursor-dot-color, etc.)
β€’ ThemeContext sets [data-theme='dark'|'light'] on <html>
β€’ global.css defines different values per theme
β€’ All cursor elements inherit the right color INSTANTLY on toggle
β€’ Zero JS needed for color β€” pure CSS variable propagation
═══════════════════════════════════════════════════════════════════════════ */
/* ─────────────────────────────────────────────────────────────
BASE DOT β€” inner precision core
───────────────────────────────────────────────────────────── */
.c-dot {
position: fixed;
pointer-events: none;
z-index: 99999;
top: 0; left: 0;
transform: translate(-50%, -50%);
width: var(--cursor-dot-size, 8px);
height: var(--cursor-dot-size, 8px);
border-radius: 50%;
background: var(--cursor-dot-color);
box-shadow: var(--cursor-glow);
mix-blend-mode: var(--cursor-blend, screen);
/* Color transitions follow theme-toggle speed */
transition:
background 0.55s cubic-bezier(0.4,0,0.2,1),
box-shadow 0.55s cubic-bezier(0.4,0,0.2,1),
mix-blend-mode 0.55s ease,
width 0.18s cubic-bezier(0.34,1.56,0.64,1),
height 0.18s cubic-bezier(0.34,1.56,0.64,1),
opacity 0.18s ease;
will-change: left, top, width, height;
}
/* ─────────────────────────────────────────────────────────────
OUTER RING β€” lagged follower
───────────────────────────────────────────────────────────── */
.c-ring {
position: fixed;
pointer-events: none;
z-index: 99998;
top: 0; left: 0;
transform: translate(-50%, -50%);
width: 38px;
height: 38px;
border-radius: 50%;
border: var(--cursor-ring-border, 2px solid rgba(0,255,238,0.65));
box-shadow: var(--cursor-ring-glow);
mix-blend-mode: var(--cursor-blend, screen);
transition:
border-color 0.55s cubic-bezier(0.4,0,0.2,1),
box-shadow 0.55s cubic-bezier(0.4,0,0.2,1),
background 0.35s ease,
mix-blend-mode 0.55s ease,
width 0.32s cubic-bezier(0.34,1.56,0.64,1),
height 0.32s cubic-bezier(0.34,1.56,0.64,1),
opacity 0.22s ease;
will-change: left, top, width, height;
}
/* ─────────────────────────────────────────────────────────────
EXPANDED STATE β€” on hover of interactive elements
───────────────────────────────────────────────────────────── */
.c-ring.expand {
width: 62px;
height: 62px;
border: var(--cursor-ring-expand-border, 2px solid rgba(191,0,255,0.85));
box-shadow: var(--cursor-expand-glow);
background: rgba(124,58,237,0.06);
}
/* Dark expand bg */
[data-theme='dark'] .c-ring.expand {
background: rgba(191,0,255,0.10);
}
/* Light expand bg β€” warm gold tint */
[data-theme='light'] .c-ring.expand {
background: rgba(217,119,6,0.10);
}
/* ─────────────────────────────────────────────────────────────
MAGNETIC DOT STATE β€” on links (dashed spinner)
───────────────────────────────────────────────────────────── */
.c-ring.on-link {
animation: ringMagSpin 1.6s linear infinite;
border-style: dashed;
border-width: 1.5px;
}
@keyframes ringMagSpin {
to { transform: translate(-50%, -50%) rotate(360deg); }
}
/* ─────────────────────────────────────────────────────────────
TRAIL RING β€” furthest lag, dreamy echo
───────────────────────────────────────────────────────────── */
.c-trail {
position: fixed;
pointer-events: none;
z-index: 99997;
top: 0; left: 0;
transform: translate(-50%, -50%);
width: 70px;
height: 70px;
border-radius: 50%;
border: 1px solid var(--cursor-trail-color);
box-shadow: var(--cursor-trail-glow);
opacity: 0.55;
mix-blend-mode: var(--cursor-blend, screen);
transition:
border-color 0.55s ease,
box-shadow 0.55s ease,
width 0.5s ease,
height 0.5s ease,
opacity 0.5s ease;
will-change: left, top;
}
/* ─────────────────────────────────────────────────────────────
CLICK BURST β€” dot pulses
───────────────────────────────────────────────────────────── */
.c-dot.clicking {
animation: dotQuantumBurst 0.38s cubic-bezier(0.34,1.56,0.64,1);
}
@keyframes dotQuantumBurst {
0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
35% { transform: translate(-50%, -50%) scale(3.2); opacity: 0.5; }
65% { transform: translate(-50%, -50%) scale(1.5); opacity: 0.8; }
100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
/* ─────────────────────────────────────────────────────────────
CLICK BURST β€” ring ripples
───────────────────────────────────────────────────────────── */
.c-ring.clicking {
animation: ringQuantumBurst 0.45s cubic-bezier(0.19,1,0.22,1);
}
@keyframes ringQuantumBurst {
0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
45% { transform: translate(-50%, -50%) scale(2.2); opacity: 0.3; }
100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
/* ─────────────────────────────────────────────────────────────
PARTICLE BURST β€” spawned on click via JS
───────────────────────────────────────────────────────────── */
.c-particle {
position: fixed;
pointer-events: none;
z-index: 99996;
top: 0; left: 0;
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--cursor-particle-color);
box-shadow: var(--cursor-glow);
transform: translate(-50%, -50%);
animation: particleQuantum 0.7s ease-out forwards;
transition: background 0.55s ease, box-shadow 0.55s ease;
}
@keyframes particleQuantum {
0% { opacity: 1; transform: translate(calc(-50% + 0px), calc(-50% + 0px)) scale(1); }
100% {
opacity: 0;
transform: translate(
calc(-50% + var(--px, 30px)),
calc(-50% + var(--py, -30px))
) scale(0.2);
}
}
/* ─────────────────────────────────────────────────────────────
MAGNETIC TRAIL DOTS β€” fading orbs left behind
───────────────────────────────────────────────────────────── */
.c-mag-dot {
position: fixed;
pointer-events: none;
z-index: 99995;
border-radius: 50%;
background: var(--cursor-dot-color);
transform: translate(-50%, -50%);
animation: magTrailFade 0.55s ease-out forwards;
transition: background 0.55s ease;
}
@keyframes magTrailFade {
0% { opacity: 0.55; width: 6px; height: 6px; }
100% { opacity: 0; width: 2px; height: 2px; }
}
/* ─────────────────────────────────────────────────────────────
SCAN LINE β€” sweeps across cursor area on theme toggle
───────────────────────────────────────────────────────────── */
.c-scan {
position: fixed;
pointer-events: none;
z-index: 99994;
top: 0; left: -100%;
width: 200px; height: 2px;
background: linear-gradient(90deg, transparent, var(--cursor-dot-color), transparent);
box-shadow: var(--cursor-glow);
animation: scanSweep 0.6s ease-out forwards;
transition: background 0.55s ease;
}
@keyframes scanSweep {
0% { left: -200px; opacity: 1; }
100% { left: calc(100vw + 200px); opacity: 0; }
}
/* ─────────────────────────────────────────────────────────────
TEXT CURSOR STATE β€” when hovering text
───────────────────────────────────────────────────────────── */
.c-dot.on-text {
width: 3px;
height: 20px;
border-radius: 2px;
animation: textCursorBlink 1.1s step-end infinite;
}
@keyframes textCursorBlink {
50% { opacity: 0; }
}
/* ─────────────────────────────────────────────────────────────
IMAGE CURSOR STATE β€” crosshair on images
───────────────────────────────────────────────────────────── */
.c-dot.on-image {
width: 36px;
height: 36px;
background: transparent;
border: 2px solid var(--cursor-dot-color);
box-shadow: var(--cursor-ring-glow), inset 0 0 8px rgba(0,255,238,0.15);
}
.c-dot.on-image::before,
.c-dot.on-image::after {
content: '';
position: absolute;
background: var(--cursor-dot-color);
}
.c-dot.on-image::before {
width: 1px; height: 12px;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
}
.c-dot.on-image::after {
width: 12px; height: 1px;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
}
/* ─────────────────────────────────────────────────────────────
HIDE ON MOBILE / TOUCH
───────────────────────────────────────────────────────────── */
@media (max-width: 768px),
(hover: none),
(pointer: coarse) {
.c-dot,
.c-ring,
.c-trail,
.c-particle,
.c-mag-dot,
.c-scan {
display: none !important;
}
}