/* ========================================================= REGULAR SCANLINES SETTINGS ========================================================= */ $scan-width: 1px; $scan-crt: false; $scan-fps: 20; $scan-color: rgba(#000, 0.30); $scan-z-index: 2147483648; $scan-moving-line: true; $scan-opacity: 0.75; /* ========================================================= CRT / S-VIDEO EFFECT SETTINGS ========================================================= */ // whole-screen softness $crt-soft-blur: 0.6px; // mild brightening / contrast to keep blur from looking muddy $crt-contrast: 1.02; $crt-saturation: 1.12; $crt-brightness: 1.00; // fake horizontal chroma bleed $crt-r-shift: -1px; $crt-b-shift: 1px; $crt-bleed-blur: 1.8px; $crt-rgb-opacity: 0.05; // subtle tube edge darkening $crt-vignette-opacity: 0.16; // optional tiny bloom $crt-glow-opacity: 0.08; /* ========================================================= MIXINS ========================================================= */ @mixin scan-crt($enabled) { @if $enabled == true { animation: scanlines 1s steps($scan-fps) infinite; } @else { animation: none; } } @mixin scan-moving($enabled) { @if $enabled == true { animation: scanline 6s linear infinite; } @else { animation: none; } } /* ========================================================= APPLY TO THE REAL APP CONTAINER ========================================================= */ /* You can add class="scanlines" to #divTwcMain or #container. Example:
*/ .scanlines { position: relative; overflow: hidden; isolation: isolate; /* This is the actual rendered weather area in your HTML. Applying the softness here affects the maps/text/icons themselves. */ #container { position: relative; z-index: 1; transform: translateZ(0); will-change: filter; filter: blur($crt-soft-blur) saturate($crt-saturation) contrast($crt-contrast) brightness($crt-brightness); } /* Red fringe overlay */ #container::before, #container::after { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 3; } #container::before { background: linear-gradient( to right, rgba(255, 0, 0, $crt-rgb-opacity) 0%, rgba(255, 0, 0, 0.01) 15%, rgba(255, 0, 0, 0.00) 50%, rgba(255, 0, 0, 0.01) 85%, rgba(255, 0, 0, $crt-rgb-opacity) 100% ); transform: translateX($crt-r-shift); filter: blur($crt-bleed-blur); mix-blend-mode: screen; } /* Blue fringe overlay */ #container::after { background: linear-gradient( to right, rgba(0, 140, 255, $crt-rgb-opacity) 0%, rgba(0, 140, 255, 0.01) 15%, rgba(0, 140, 255, 0.00) 50%, rgba(0, 140, 255, 0.01) 85%, rgba(0, 140, 255, $crt-rgb-opacity) 100% ); transform: translateX($crt-b-shift); filter: blur($crt-bleed-blur); mix-blend-mode: screen; } /* Moving scanline */ &:before, &:after { display: block; pointer-events: none; content: ''; position: absolute; left: 0; right: 0; } &:before { height: var(--scanline-thickness, $scan-width); z-index: $scan-z-index + 2; background: $scan-color; opacity: $scan-opacity; @include scan-moving($scan-moving-line); } /* Regular scanline mask */ &:after { top: 0; bottom: 0; z-index: $scan-z-index; background: repeating-linear-gradient( to bottom, transparent 0, transparent var(--scanline-thickness, $scan-width), $scan-color var(--scanline-thickness, $scan-width), $scan-color calc(var(--scanline-thickness, $scan-width) * 2) ); @include scan-crt($scan-crt); } /* Vignette layer Added as an inset shadow so you don't need extra HTML */ box-shadow: inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity), inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity); } /* ========================================================= OPTIONAL: only affect active weather panels, not menus ========================================================= */ /* If the controls / bottom nav get too blurry, move the blur from #container to the weather slides only: */ .scanlines.crt-panels-only { #container { filter: none; } .weather-display { filter: blur($crt-soft-blur) saturate($crt-saturation) contrast($crt-contrast) brightness($crt-brightness); transform: translateZ(0); } } /* ========================================================= OPTIONAL: make text slightly glow like old TV phosphors ========================================================= */ .scanlines { .header, .main, .scroll, .date-time, .city, .temp, .condition, .location, .label, .value, .title { text-shadow: 0 0 1px rgba(255, 255, 255, 0.18), 0 0 2px rgba(255, 255, 255, 0.06); } } /* ========================================================= ANIMATIONS ========================================================= */ @keyframes scanline { 0% { transform: translate3d(0, 200000%, 0); } } @keyframes scanlines { 0% { background-position: 0 50%; } }