diff --git a/.gitignore b/.gitignore
index 7ed4bca..e758bf9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,5 @@ dist/*
!dist/readme.txt
#environment variables
-.env
\ No newline at end of file
+.env
+nohup.out
diff --git a/package-lock.json b/package-lock.json
index a17bcf4..42bc6e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1551,9 +1551,6 @@
"arm"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1575,9 +1572,6 @@
"arm"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1599,9 +1593,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1623,9 +1614,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1647,9 +1635,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -1671,9 +1656,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -3466,9 +3448,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
- "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
+ "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5320,9 +5302,9 @@
}
},
"node_modules/filelist/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
+ "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7575,9 +7557,9 @@
}
},
"node_modules/lodash": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
- "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"dev": true,
"license": "MIT"
},
diff --git a/server/images/backgrounds/1.png b/server/images/backgrounds/1.png
index c5b0870..d2986c5 100644
Binary files a/server/images/backgrounds/1.png and b/server/images/backgrounds/1.png differ
diff --git a/server/images/backgrounds/1.png.old b/server/images/backgrounds/1.png.old
new file mode 100644
index 0000000..c5b0870
Binary files /dev/null and b/server/images/backgrounds/1.png.old differ
diff --git a/server/images/backgrounds/2.png b/server/images/backgrounds/2.png
index adcdebc..ccb9b22 100644
Binary files a/server/images/backgrounds/2.png and b/server/images/backgrounds/2.png differ
diff --git a/server/images/backgrounds/2.png.old b/server/images/backgrounds/2.png.old
new file mode 100644
index 0000000..adcdebc
Binary files /dev/null and b/server/images/backgrounds/2.png.old differ
diff --git a/server/images/logos/logo-corner.png b/server/images/logos/logo-corner.png
index cce7cd4..3e9862f 100644
Binary files a/server/images/logos/logo-corner.png and b/server/images/logos/logo-corner.png differ
diff --git a/server/images/logos/logo-corner.png.original b/server/images/logos/logo-corner.png.original
new file mode 100644
index 0000000..cce7cd4
Binary files /dev/null and b/server/images/logos/logo-corner.png.original differ
diff --git a/server/styles/scss/shared/_scanlines.scss b/server/styles/scss/shared/_scanlines.scss
index 66636f1..783fddb 100644
--- a/server/styles/scss/shared/_scanlines.scss
+++ b/server/styles/scss/shared/_scanlines.scss
@@ -1,130 +1,243 @@
-/* REGULAR SCANLINES SETTINGS */
+/* =========================================================
+ REGULAR SCANLINES SETTINGS
+ ========================================================= */
-// width of 1 scanline (responsive units to prevent banding)
$scan-width: 1px;
-$scan-width-scaled: 0.15vh; // viewport-relative unit for better scaling
-
-// emulates a damage-your-eyes bad pre-2000 CRT screen ♥ (true, false)
$scan-crt: false;
-
-// frames-per-second (should be > 1), only applies if $scan-crt: true;
$scan-fps: 20;
-
-// scanline-color (rgba)
-$scan-color: rgba(#000, .3);
-
-// set z-index on 8, like in ♥ 8-bits ♥, or…
-// set z-index on 2147483648 or more to enable scanlines on Chrome fullscreen (doesn't work in Firefox or IE);
+$scan-color: rgba(#000, 0.30);
$scan-z-index: 2147483648;
-/* MOVING SCANLINE SETTINGS */
-
-// moving scanline (true, false)
$scan-moving-line: true;
+$scan-opacity: 0.75;
-// opacity of the moving scanline
-$scan-opacity: .75;
+/* =========================================================
+ CRT / S-VIDEO EFFECT SETTINGS
+ ========================================================= */
-/* MIXINS */
+// whole-screen softness
+$crt-soft-blur: 0.45px;
-// apply CRT animation: @include scan-crt($scan-crt);
-@mixin scan-crt($scan-crt) {
- @if $scan-crt==true {
- animation: scanlines 1s steps($scan-fps) infinite;
- }
+// mild brightening / contrast to keep blur from looking muddy
+$crt-contrast: 1.04;
+$crt-saturation: 1.08;
+$crt-brightness: 0.98;
- @else {
- animation: none;
- }
+// fake horizontal chroma bleed
+$crt-r-shift: -0.7px;
+$crt-b-shift: 0.7px;
+$crt-bleed-blur: 1.2px;
+$crt-rgb-opacity: 0.04;
+
+// subtle tube edge darkening
+$crt-vignette-opacity: 0.16;
+
+// optional tiny bloom
+$crt-glow-opacity: 0.05;
+
+/* =========================================================
+ MIXINS
+ ========================================================= */
+
+@mixin scan-crt($enabled) {
+ @if $enabled == true {
+ animation: scanlines 1s steps($scan-fps) infinite;
+ } @else {
+ animation: none;
+ }
}
-// apply CRT animation: @include scan-crt($scan-crt);
-@mixin scan-moving($scan-moving-line) {
- @if $scan-moving-line==true {
- animation: scanline 6s linear infinite;
- }
-
- @else {
- animation: none;
- }
+@mixin scan-moving($enabled) {
+ @if $enabled == true {
+ animation: scanline 6s linear infinite;
+ } @else {
+ animation: none;
+ }
}
-/* CSS .scanlines CLASS */
+/* =========================================================
+ APPLY TO THE REAL APP CONTAINER
+ ========================================================= */
+
+/*
+ You can add class="scanlines" to #divTwcMain or #container.
+ Example:
+
+*/
.scanlines {
- position: relative;
- overflow: hidden; // only to animate the unique scanline
+ position: relative;
+ overflow: hidden;
+ isolation: isolate;
- &:before,
- &:after {
- display: block;
- pointer-events: none;
- content: '';
- position: absolute;
- }
+ /*
+ 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;
- // unique scanline travelling on the screen
- &:before {
- // position: absolute;
- // bottom: 100%;
- width: 100%;
- height: $scan-width * 1;
- z-index: $scan-z-index + 1;
- background: $scan-color;
- opacity: $scan-opacity;
- // animation: scanline 6s linear infinite;
- @include scan-moving($scan-moving-line);
- }
+ filter:
+ blur($crt-soft-blur)
+ saturate($crt-saturation)
+ contrast($crt-contrast)
+ brightness($crt-brightness);
+ }
- // the scanlines, so! - with responsive scaling for low-res displays
- &:after {
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: $scan-z-index;
- // repeating-linear-gradient is more efficient than linear-gradient+background-size because it doesn't require the browser to calculate tiling
- background: repeating-linear-gradient(to bottom,
- transparent 0,
- transparent $scan-width,
- $scan-color $scan-width,
- $scan-color calc($scan-width * 2));
- @include scan-crt($scan-crt);
+ /*
+ Red fringe overlay
+ */
+ #container::before,
+ #container::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ z-index: 3;
+ }
- // Prevent sub-pixel aliasing on scaled displays
- image-rendering: crisp-edges;
- image-rendering: pixelated;
- }
+ #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;
+ }
- // Scanlines use dynamic thickness calculated by JavaScript
- // JavaScript calculates optimal thickness to prevent banding at any scale factor
- // The --scanline-thickness custom property is set by applyScanlineScaling()
- // The modes (hairline, thin, medium, thick) force the base thickness selection
- // Some modes may appear the same (e.g. hairline and thin) depending on the display
- &:before {
- height: var(--scanline-thickness, $scan-width);
- }
+ /*
+ 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;
+ }
- &:after {
- 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));
- }
+ /*
+ 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);
}
-/* ANIMATE UNIQUE SCANLINE */
+/* =========================================================
+ 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);
- // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; }
- }
+ 0% {
+ transform: translate3d(0, 200000%, 0);
+ }
}
@keyframes scanlines {
- 0% {
- background-position: 0 50%;
- // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; }
- }
+ 0% {
+ background-position: 0 50%;
+ }
}
+
diff --git a/server/styles/scss/shared/_scanlines.scss.old b/server/styles/scss/shared/_scanlines.scss.old
new file mode 100644
index 0000000..66636f1
--- /dev/null
+++ b/server/styles/scss/shared/_scanlines.scss.old
@@ -0,0 +1,130 @@
+/* REGULAR SCANLINES SETTINGS */
+
+// width of 1 scanline (responsive units to prevent banding)
+$scan-width: 1px;
+$scan-width-scaled: 0.15vh; // viewport-relative unit for better scaling
+
+// emulates a damage-your-eyes bad pre-2000 CRT screen ♥ (true, false)
+$scan-crt: false;
+
+// frames-per-second (should be > 1), only applies if $scan-crt: true;
+$scan-fps: 20;
+
+// scanline-color (rgba)
+$scan-color: rgba(#000, .3);
+
+// set z-index on 8, like in ♥ 8-bits ♥, or…
+// set z-index on 2147483648 or more to enable scanlines on Chrome fullscreen (doesn't work in Firefox or IE);
+$scan-z-index: 2147483648;
+
+/* MOVING SCANLINE SETTINGS */
+
+// moving scanline (true, false)
+$scan-moving-line: true;
+
+// opacity of the moving scanline
+$scan-opacity: .75;
+
+/* MIXINS */
+
+// apply CRT animation: @include scan-crt($scan-crt);
+@mixin scan-crt($scan-crt) {
+ @if $scan-crt==true {
+ animation: scanlines 1s steps($scan-fps) infinite;
+ }
+
+ @else {
+ animation: none;
+ }
+}
+
+// apply CRT animation: @include scan-crt($scan-crt);
+@mixin scan-moving($scan-moving-line) {
+ @if $scan-moving-line==true {
+ animation: scanline 6s linear infinite;
+ }
+
+ @else {
+ animation: none;
+ }
+}
+
+/* CSS .scanlines CLASS */
+
+.scanlines {
+ position: relative;
+ overflow: hidden; // only to animate the unique scanline
+
+ &:before,
+ &:after {
+ display: block;
+ pointer-events: none;
+ content: '';
+ position: absolute;
+ }
+
+ // unique scanline travelling on the screen
+ &:before {
+ // position: absolute;
+ // bottom: 100%;
+ width: 100%;
+ height: $scan-width * 1;
+ z-index: $scan-z-index + 1;
+ background: $scan-color;
+ opacity: $scan-opacity;
+ // animation: scanline 6s linear infinite;
+ @include scan-moving($scan-moving-line);
+ }
+
+ // the scanlines, so! - with responsive scaling for low-res displays
+ &:after {
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $scan-z-index;
+ // repeating-linear-gradient is more efficient than linear-gradient+background-size because it doesn't require the browser to calculate tiling
+ background: repeating-linear-gradient(to bottom,
+ transparent 0,
+ transparent $scan-width,
+ $scan-color $scan-width,
+ $scan-color calc($scan-width * 2));
+ @include scan-crt($scan-crt);
+
+ // Prevent sub-pixel aliasing on scaled displays
+ image-rendering: crisp-edges;
+ image-rendering: pixelated;
+ }
+
+ // Scanlines use dynamic thickness calculated by JavaScript
+ // JavaScript calculates optimal thickness to prevent banding at any scale factor
+ // The --scanline-thickness custom property is set by applyScanlineScaling()
+ // The modes (hairline, thin, medium, thick) force the base thickness selection
+ // Some modes may appear the same (e.g. hairline and thin) depending on the display
+ &:before {
+ height: var(--scanline-thickness, $scan-width);
+ }
+
+ &:after {
+ 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));
+ }
+}
+
+/* ANIMATE UNIQUE SCANLINE */
+@keyframes scanline {
+ 0% {
+ transform: translate3d(0, 200000%, 0);
+ // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; }
+ }
+}
+
+@keyframes scanlines {
+ 0% {
+ background-position: 0 50%;
+ // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; }
+ }
+}