@import './tokens.css'; /* ── Grain overlay ───────────────────────────────────── */ body::before { content: ''; position: fixed; inset: 0; z-index: 9998; pointer-events: none; opacity: 0.035; mix-blend-mode: multiply; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-repeat: repeat; background-size: 180px; } /* ── Custom cursor ───────────────────────────────────── */ .cursor-dot, .cursor-ring { position: fixed; top: 0; left: 0; pointer-events: none; z-index: 10002; transform: translate(-50%, -50%); transition: opacity 0.3s; } .cursor-dot { width: 6px; height: 6px; background: var(--accent); border-radius: 50%; } .cursor-ring { width: 32px; height: 32px; border: 1px solid var(--accent); border-radius: 50%; opacity: 0.6; transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1), height 0.25s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.25s, opacity 0.25s; } .cursor-ring.is-active { width: 48px; height: 48px; border-color: var(--accent-light); opacity: 0.9; } body.is-hovering .cursor-ring { width: 48px; height: 48px; border-color: var(--accent-light); } @media (hover: none), (pointer: coarse) { .cursor-dot, .cursor-ring { display: none; } * { cursor: auto !important; } } @media (hover: hover) and (pointer: fine) { body, button, a, input, [data-cursor] { cursor: none; } } @media (prefers-reduced-motion: reduce) { .cursor-ring.is-active { transition: none; } } /* ── Reveal animation ──────────────────────────────────── */ .reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.7s ease, transform 0.7s ease; } .reveal.is-in { opacity: 1; transform: none; } @media (prefers-reduced-motion: reduce) { .reveal { transform: none; } }