.filmnoir-tint { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 10000; background-color: #8c7355; mix-blend-mode: color; } .filmnoir-effects { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 1100; } /* Film grain */ .filmnoir-grain { position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background-image: url('data:image/svg+xml;utf8,'); animation: grain-dance 0.2s steps(4) infinite; pointer-events: none; mix-blend-mode: overlay; opacity: 0.3; } /* Vignette */ .filmnoir-vignette { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; background: radial-gradient(circle at center, transparent 50%, rgba(0,0,0,0.8) 120%); box-shadow: inset 0 0 100px rgba(0,0,0,0.6); } /* Occasional flicker and scratch */ .filmnoir-scratches { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; background: linear-gradient(to right, transparent 50%, rgba(255,255,255,0.2) 51%, transparent 52%); background-size: 200% 100%; animation: scratch 4s infinite linear, flicker 6s infinite alternate; opacity: 0.2; mix-blend-mode: screen; } @keyframes grain-dance { 0% { transform: translate(0,0); } 25% { transform: translate(-5%,-5%); } 50% { transform: translate(-10%,5%); } 75% { transform: translate(5%,-10%); } 100% { transform: translate(0,0); } } @keyframes scratch { 0% { background-position: -200% 0; } 10% { background-position: 200% 0; } 100% { background-position: 200% 0; } } @keyframes flicker { 0% { opacity: 0.2; } 5% { opacity: 0.1; } 10% { opacity: 0.3; } 15% { opacity: 0.2; } 50% { opacity: 0.15; } 55% { opacity: 0.25; } 100% { opacity: 0.2; } }