summaryrefslogtreecommitdiffci
diff options
from:
to:
context:
space:
mode:
authorGravatar Saya Andy <145215889+SayaAndy@users.noreply.github.com> 2026-05-03 12:37:21 +0700
committerGravatar GitHub <noreply@github.com> 2026-05-03 12:37:21 +0700
commit658c9860336fedeef5d25e48fb1fc25151b45768 (patch)
tree60cb4ecf5ad7aaf6d45d78f2940f63dff07486da
parent82353c59737d173776822d8e4255802bf7ac5685 (diff)
parent8a66768bee63f3e813fb4ba920b3155db885c4bd (diff)
downloadweb-658c9860336fedeef5d25e48fb1fc25151b45768.tar.gz
web-658c9860336fedeef5d25e48fb1fc25151b45768.zip
v0.14.2 (#29)v0.14.2
- [feat: new svg icon for dark/light themes](https://github.com/SayaAndy/saya-today-web/commit/8a66768bee63f3e813fb4ba920b3155db885c4bd) - format: svg/html formatting
-rw-r--r--static/favicon-dark.svg16
-rw-r--r--static/favicon-light.svg16
-rw-r--r--static/favicon.icobin5694 -> 0 bytes
-rw-r--r--static/input.css123
-rw-r--r--views/layouts/general-page.html1027
-rw-r--r--views/pages/global-map.html21
-rw-r--r--views/pages/unsubscribe-page.html12
7 files changed, 801 insertions, 414 deletions
diff --git a/static/favicon-dark.svg b/static/favicon-dark.svg
new file mode 100644
index 0000000..f09a1bf
--- /dev/null
+++ b/static/favicon-dark.svg
@@ -0,0 +1,16 @@
+<svg role="img" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" id="Lutris--Streamline-Simple-Icons" height="120" width="120">
+ <desc>
+ Lutris Streamline Icon: https://streamlinehq.com
+ </desc>
+ <defs>
+ <linearGradient gradientTransform="rotate(150, 0.5, 0.5)" x1="50%" y1="0%" x2="50%" y2="100%" id="gradient">
+ <stop stop-color="hsl(31.4, 100%, 70.8%)" stop-opacity="1" offset="0%"></stop><stop stop-color="hsl(17, 100%, 31%)" stop-opacity="1" offset="100%"></stop>
+ </linearGradient>
+ <filter id="filter" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+ <feTurbulence type="fractalNoise" baseFrequency="0.005 0.003" numOctaves="1" seed="2" stitchTiles="stitch" x="0%" y="0%" width="100%" height="100%" result="turbulence"></feTurbulence>
+ <feGaussianBlur stdDeviation="20 0" x="0%" y="0%" width="100%" height="100%" in="turbulence" edgeMode="duplicate" result="blur"></feGaussianBlur>
+ <feBlend mode="color-dodge" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" in2="blur" result="blend"></feBlend>
+ </filter>
+ </defs>
+ <path d="m106.155 94.45 0.005 -0.01c-6.465 16.215 -26.09 26.16 -47.235 25.525C26.5 119.965 0 92.4 0 59.53S26.38 0.005 58.925 0.005c8.965 0 17.465 2.03 25.075 5.65 0.405 -0.885 1.355 -2.72 2.255 -2.785 1.19 -0.085 1.87 0.685 2.63 1.545 0.77 0.86 2.3 2.145 2.3 2.145s6.965 -2.405 14.775 1.885c7.815 4.29 8.915 5.58 10.45 8.58 0.76 1.505 0.975 4.145 1 6.41a3.98 3.98 0 0 0 -0.35 -0.015c-2.48 0 -4.8 2.275 -4.8 5.4 0 1.315 0.41 2.48 1.075 3.39l-0.05 0.035a7.525 7.525 0 0 0 -0.66 0.05 93.52 93.52 0 0 0 -1.945 -0.71 12.65 12.65 0 0 1 -4.1 -2.36 7.01 7.01 0 0 0 -5.98 -10.56c-1.915 0 -3.65 0.78 -4.91 2.05 -2.36 -1.355 -5.87 -2.41 -12.635 -2.825l-2.035 -0.055c-11.41 0.06 -18.055 1.395 -29.895 6.505 -3.015 1.415 -6.03 3.075 -8.925 5.005 -2.115 1.5 -3.195 3.35 -3.545 5.685a6.63 6.63 0 0 0 6.15 6.865h0.210c6.35 0.3 10.195 9.95 10.315 12.485 0.02 0.25 0.02 0.115 0.015 0.4 -0.16 3.635 -1.85 6.335 -5.44 6.23a6.155 6.155 0 0 1 -4.88 -2.47c-0.315 -0.385 -0.515 -0.86 -0.795 -1.27 -3.33 -5.405 -8.66 -6.80 -13.855 -7.615 -2.19 -0.34 -5.365 -0.61 -6.55 1.25a41.4 41.4 0 0 0 -2.885 15.315c-0.1 25.18 20.205 45.59 45.13 45.59 12.875 0 26.745 -4.76 34.965 -13.5l-0.175 0.15c-8.86 7.365 -23.3 9.705 -30.135 9.705 -21.51 0 -39.09 -16.16 -39.09 -37.89 0 -6.38 1.44 -11.98 4.07 -16.8 2.475 0.915 4.735 2.415 6.4 5.11a1.2 1.2 0 0 0 0.065 0.1050c0.32 0.46 0.555 0.985 0.91 1.42 2.12 2.62 4.405 3.29 6.71 3.4h0.05c2.15 0.065 3.84 -0.6 5.12 -1.71 1.735 -1.5 2.75 -3.95 2.885 -6.91v-0.07c0.01 -0.425 0 -0.265 -0.02 -0.56 -0.12 -1.88 -1.665 -6.59 -4.53 -10.135 -1.33 -1.655 -2.935 -3.035 -4.75 -3.87l0.6 -0.37c3.78 -2.285 11.82 -4.885 22.96 -3.19 5.65 0.865 10.275 2.095 17.415 4.395 8.285 2.67 12.895 6.395 19.27 7.135 0.75 0.085 1.505 0.09 2.25 0.015 2.05 5.645 3.17 11.75 3.17 18.105 0 10.34 -2.95 19.975 -8.055 28.1zm9.735 -61.37s-0.575 1.005 -1.82 1.61c-0.515 0.25 -1.41 -0.375 -2.25 0.5 -1.795 3.63 2.58 6.66 4.615 6.575 2.04 -0.085 3.65 -2.16 3.56 -3.965 -0.085 -2.79 -4.1 -4.72 -4.1 -4.72zm1.17 -7.16c1.275 0 2.31 1.3 2.31 2.9 0 1.6 -1.035 2.9 -2.31 2.9 -1.27 0 -2.3 -1.3 -2.3 -2.9 0 -1.6 1.03 -2.9 2.3 -2.9zm-16.46 -4.755c2.46 0 4.45 2.015 4.45 4.5a4.475 4.475 0 0 1 -4.45 4.49 4.475 4.475 0 0 1 -4.45 -4.495c0 -2.48 1.995 -4.495 4.45 -4.495z" fill="url(#gradient)" filter="url(#filter)" stroke-width="5"></path>
+</svg>
diff --git a/static/favicon-light.svg b/static/favicon-light.svg
new file mode 100644
index 0000000..e7ed6eb
--- /dev/null
+++ b/static/favicon-light.svg
@@ -0,0 +1,16 @@
+<svg role="img" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" id="Lutris--Streamline-Simple-Icons" height="120" width="120">
+ <desc>
+ Lutris Streamline Icon: https://streamlinehq.com
+ </desc>
+ <defs>
+ <linearGradient gradientTransform="rotate(150, 0.5, 0.5)" x1="50%" y1="0%" x2="50%" y2="100%" id="gradient">
+ <stop stop-color="hsl(30.1, 100%, 44.1%)" stop-opacity="1" offset="0%"></stop><stop stop-color="hsl(23.1, 90.7%, 25.3%)" stop-opacity="1" offset="100%"></stop>
+ </linearGradient>
+ <filter id="filter" x="-20%" y="-20%" width="140%" height="140%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+ <feTurbulence type="fractalNoise" baseFrequency="0.005 0.003" numOctaves="1" seed="2" stitchTiles="stitch" x="0%" y="0%" width="100%" height="100%" result="turbulence"></feTurbulence>
+ <feGaussianBlur stdDeviation="20 0" x="0%" y="0%" width="100%" height="100%" in="turbulence" edgeMode="duplicate" result="blur"></feGaussianBlur>
+ <feBlend mode="color-dodge" x="0%" y="0%" width="100%" height="100%" in="SourceGraphic" in2="blur" result="blend"></feBlend>
+ </filter>
+ </defs>
+ <path d="m106.155 94.45 0.005 -0.01c-6.465 16.215 -26.09 26.16 -47.235 25.525C26.5 119.965 0 92.4 0 59.53S26.38 0.005 58.925 0.005c8.965 0 17.465 2.03 25.075 5.65 0.405 -0.885 1.355 -2.72 2.255 -2.785 1.19 -0.085 1.87 0.685 2.63 1.545 0.77 0.86 2.3 2.145 2.3 2.145s6.965 -2.405 14.775 1.885c7.815 4.29 8.915 5.58 10.45 8.58 0.76 1.505 0.975 4.145 1 6.41a3.98 3.98 0 0 0 -0.35 -0.015c-2.48 0 -4.8 2.275 -4.8 5.4 0 1.315 0.41 2.48 1.075 3.39l-0.05 0.035a7.525 7.525 0 0 0 -0.66 0.05 93.52 93.52 0 0 0 -1.945 -0.71 12.65 12.65 0 0 1 -4.1 -2.36 7.01 7.01 0 0 0 -5.98 -10.56c-1.915 0 -3.65 0.78 -4.91 2.05 -2.36 -1.355 -5.87 -2.41 -12.635 -2.825l-2.035 -0.055c-11.41 0.06 -18.055 1.395 -29.895 6.505 -3.015 1.415 -6.03 3.075 -8.925 5.005 -2.115 1.5 -3.195 3.35 -3.545 5.685a6.63 6.63 0 0 0 6.15 6.865h0.210c6.35 0.3 10.195 9.95 10.315 12.485 0.02 0.25 0.02 0.115 0.015 0.4 -0.16 3.635 -1.85 6.335 -5.44 6.23a6.155 6.155 0 0 1 -4.88 -2.47c-0.315 -0.385 -0.515 -0.86 -0.795 -1.27 -3.33 -5.405 -8.66 -6.80 -13.855 -7.615 -2.19 -0.34 -5.365 -0.61 -6.55 1.25a41.4 41.4 0 0 0 -2.885 15.315c-0.1 25.18 20.205 45.59 45.13 45.59 12.875 0 26.745 -4.76 34.965 -13.5l-0.175 0.15c-8.86 7.365 -23.3 9.705 -30.135 9.705 -21.51 0 -39.09 -16.16 -39.09 -37.89 0 -6.38 1.44 -11.98 4.07 -16.8 2.475 0.915 4.735 2.415 6.4 5.11a1.2 1.2 0 0 0 0.065 0.1050c0.32 0.46 0.555 0.985 0.91 1.42 2.12 2.62 4.405 3.29 6.71 3.4h0.05c2.15 0.065 3.84 -0.6 5.12 -1.71 1.735 -1.5 2.75 -3.95 2.885 -6.91v-0.07c0.01 -0.425 0 -0.265 -0.02 -0.56 -0.12 -1.88 -1.665 -6.59 -4.53 -10.135 -1.33 -1.655 -2.935 -3.035 -4.75 -3.87l0.6 -0.37c3.78 -2.285 11.82 -4.885 22.96 -3.19 5.65 0.865 10.275 2.095 17.415 4.395 8.285 2.67 12.895 6.395 19.27 7.135 0.75 0.085 1.505 0.09 2.25 0.015 2.05 5.645 3.17 11.75 3.17 18.105 0 10.34 -2.95 19.975 -8.055 28.1zm9.735 -61.37s-0.575 1.005 -1.82 1.61c-0.515 0.25 -1.41 -0.375 -2.25 0.5 -1.795 3.63 2.58 6.66 4.615 6.575 2.04 -0.085 3.65 -2.16 3.56 -3.965 -0.085 -2.79 -4.1 -4.72 -4.1 -4.72zm1.17 -7.16c1.275 0 2.31 1.3 2.31 2.9 0 1.6 -1.035 2.9 -2.31 2.9 -1.27 0 -2.3 -1.3 -2.3 -2.9 0 -1.6 1.03 -2.9 2.3 -2.9zm-16.46 -4.755c2.46 0 4.45 2.015 4.45 4.5a4.475 4.475 0 0 1 -4.45 4.49 4.475 4.475 0 0 1 -4.45 -4.495c0 -2.48 1.995 -4.495 4.45 -4.495z" fill="url(#gradient)" filter="url(#filter)" stroke-width="5"></path>
+</svg>
diff --git a/static/favicon.ico b/static/favicon.ico
deleted file mode 100644
index 33eb226..0000000
--- a/static/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/static/input.css b/static/input.css
index cdab1f0..5d8de42 100644
--- a/static/input.css
+++ b/static/input.css
@@ -46,7 +46,8 @@ html {
@utility bg-paper-* {
background-image: --value([image], [url]), var(--bg-paper);
background-size: --value("auto", "cover", "contain"), 128px;
- background-repeat: --value("repeat", "repeat-x", "repeat-y", "no-repeat"), repeat;
+ background-repeat:
+ --value("repeat", "repeat-x", "repeat-y", "no-repeat"), repeat;
background-blend-mode: --value("overlay", "multiply", "normal"), normal;
}
@@ -143,7 +144,9 @@ body {
--color-leaflet-text: var(--color-main-hard);
--color-leaflet-link: var(--color-main-medium);
--color-leaflet-link-hover: var(--color-main-soft);
- --interlocked-hexagons-background: url('https://storage.yandexcloud.kz/sayauz-static/themes/lettuce/linen-fabric.webp'), url('https://storage.yandexcloud.kz/sayauz-static/themes/lettuce/lettuce-tiles.svg');
+ --interlocked-hexagons-background:
+ url("https://storage.yandexcloud.kz/sayauz-static/themes/lettuce/linen-fabric.webp"),
+ url("https://storage.yandexcloud.kz/sayauz-static/themes/lettuce/lettuce-tiles.svg");
--interlocked-hexagons-background-repeat: repeat, repeat;
--interlocked-hexagons-background-size: 11dvh, 20dvh;
--squares-and-triangles-background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%23bbd095%22%2F%3E%3Cpath%20fill%3D%22%23f5ede1%22%20d%3D%22M0%200v6.77L6.72%200zm8.91%200L0%208.96v3.86L12.83%200zm6.11%200L0%2015.06v3.87L18.9%200zm6.11%200L0%2021.12v3.92L25%200zM25%200l25%2024.99v-3.87L28.87%200zm25%2024.99%2025%2024.98L100%2025%2075%200zm-50%20.05v3.87l21.13%2021.12H25l-25-25zm25%2024.99h3.87L50%2028.9v-3.87zm0%200L0%2075l25%2025%2025-24.99zM50%2075l25-24.98h-3.87L50%2071.14v3.87zm0%200v3.87L71.13%20100H75L50%2075.01zm25%2025h3.87L100%2078.88v-3.87zm25-24.99v-3.87L78.87%2050.03H75L100%2075zM31.1%200%2050%2018.93v-3.87L34.98%200h-3.87zm6.07%200L50%2012.82V8.96L41.04%200zm6.1%200L50%206.77V0h-6.72zM25%202.19%202.14%2025.04H25zm0%2022.85v22.8l22.81-22.8zM75%203.92l21.13%2021.12L75%2046.16%2053.87%2025.04zm0%202.19L56.06%2025.04l18.89%2018.88%2018.94-18.88L75%206.1zm0%203.92%2015.07%2015L75%2040.06%2059.98%2025.04zm0%202.18L62.17%2025.04%2075%2037.86l12.83-12.82L75%2012.2zm0%203.82%208.96%209L75%2033.95%2066.04%2025zm0%202.24-6.72%206.77L75%2031.76l6.77-6.72h-.05zM0%2031.09v3.87l15.02%2015.07h3.87zm50%200L31.1%2050.03h3.88L50%2034.96V31.1zM0%2037.2v3.87l8.91%208.96h3.92zm50%200L37.17%2050.03h3.87L50%2041.07zM0%2043.3v6.73h6.72zm50%200-6.72%206.73H50zm0%206.73v6.71l6.72-6.71zm8.96%200L50%2058.93v3.92l12.83-12.82zm6.06%200L50%2065.03v3.88l18.94-18.88zm16.09%200L100%2068.9v-3.87l-15.02-15zm6.11%200L100%2062.85v-3.92l-8.91-8.9zm6.06%200%206.72%206.71v-6.71zM75%2052.2%2052.19%2075H75zM75%2075v22.8L97.81%2075zM25%2053.9l21.13%2021.12L25%2096.13%203.87%2075.01zm0%202.2L6.1%2074.95l18.95%2018.88%2018.9-18.88L25%2056.08zm0%203.9%2015.02%2015.01L25%2090.03%209.98%2075zm0%202.19L12.17%2075%2025%2087.84%2037.83%2075%2025%2062.2zm0%203.87L33.96%2075%2025%2083.97%2016.04%2075zm0%202.23-6.72%206.72L25%2081.73l6.72-6.72L25%2068.3zm25%2012.83v3.87L65.02%20100h3.87zm50%200L81.1%20100h3.88L100%2084.99zm-50%206.06v3.86l8.96%208.96h3.87zm50%200L87.22%20100h3.87l8.91-8.96zm-50%206.1V100h6.72zm50%200L93.28%20100H100z%22%2F%3E%3C%2Fsvg%3E");
@@ -173,7 +176,44 @@ body {
--color-leaflet-text: var(--color-background-dark);
--color-leaflet-link: var(--color-background-dark);
--color-leaflet-link-hover: var(--color-background-light);
- --interlocked-hexagons-background: radial-gradient(33.5% 25% at 100% 82%, rgba(190, 227, 248, 0.2) 0%, rgba(197, 179, 246, 0.13) 33.33%, rgba(255, 0, 0, 0) 100%), radial-gradient(54% 25% at 55% 100%, rgba(190, 227, 248, 0.2) 0%, rgba(197, 179, 246, 0.13) 33.33%, rgba(255, 0, 0, 0) 100%), radial-gradient(37% 19.5% at 20% 100%, rgba(176, 220, 248, 0.3) 0%, rgba(197, 172, 247, 0.2) 33.33%, rgba(255, 0, 0, 0) 100%), radial-gradient(63% 34.5% at 66% 77%, rgba(190, 227, 248, 0.15) 0%, rgba(197, 179, 246, 0.1) 33.33%, rgba(255, 0, 0, 0) 100%), linear-gradient(0deg, #2f5883 0%, #2f4e7a 4.75%, #2e4472 9.5%, #2a3065 19%, #272e57 26.5%, #242b4b 34%, #1f2437 49%, #1c2030 57.75%, #1a1b29 66.5%, #13131b 84%);
+ --interlocked-hexagons-background:
+ radial-gradient(
+ 33.5% 25% at 100% 82%,
+ rgba(190, 227, 248, 0.2) 0%,
+ rgba(197, 179, 246, 0.13) 33.33%,
+ rgba(255, 0, 0, 0) 100%
+ ),
+ radial-gradient(
+ 54% 25% at 55% 100%,
+ rgba(190, 227, 248, 0.2) 0%,
+ rgba(197, 179, 246, 0.13) 33.33%,
+ rgba(255, 0, 0, 0) 100%
+ ),
+ radial-gradient(
+ 37% 19.5% at 20% 100%,
+ rgba(176, 220, 248, 0.3) 0%,
+ rgba(197, 172, 247, 0.2) 33.33%,
+ rgba(255, 0, 0, 0) 100%
+ ),
+ radial-gradient(
+ 63% 34.5% at 66% 77%,
+ rgba(190, 227, 248, 0.15) 0%,
+ rgba(197, 179, 246, 0.1) 33.33%,
+ rgba(255, 0, 0, 0) 100%
+ ),
+ linear-gradient(
+ 0deg,
+ #2f5883 0%,
+ #2f4e7a 4.75%,
+ #2e4472 9.5%,
+ #2a3065 19%,
+ #272e57 26.5%,
+ #242b4b 34%,
+ #1f2437 49%,
+ #1c2030 57.75%,
+ #1a1b29 66.5%,
+ #13131b 84%
+ );
--interlocked-hexagons-background-repeat: no-repeat;
--interlocked-hexagons-background-size: 100dvw 100dvh;
--squares-and-triangles-background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2260%22%20height%3D%2260%22%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22%2313131b%22%2F%3E%3Cpath%20fill%3D%22none%22%20stroke%3D%22%23363645%22%20stroke-width%3D%22.5%22%20d%3D%22M10%2050H0m60-40H50m0%2040v10M10%200v10m21%2030v20m0-60v20m9%2010h20M0%2030h20m0%2010h20V20H20v10zM10%2010h40v40H10zM0%200h60v60H0z%22%2F%3E%3C%2Fsvg%3E");
@@ -203,10 +243,10 @@ body {
--color-leaflet-text: var(--color-background-dark);
--color-leaflet-link: var(--color-background-dark);
--color-leaflet-link-hover: var(--color-background-light);
- --interlocked-hexagons-background: url('https://storage.yandexcloud.kz/sayauz-static/themes/ram/ram-background.webp');
+ --interlocked-hexagons-background: url("https://storage.yandexcloud.kz/sayauz-static/themes/ram/ram-background.webp");
--interlocked-hexagons-background-repeat: repeat;
--interlocked-hexagons-background-size: auto;
- --squares-and-triangles-background: url('https://storage.yandexcloud.kz/sayauz-static/themes/ram/ram-sidebar.webp');
+ --squares-and-triangles-background: url("https://storage.yandexcloud.kz/sayauz-static/themes/ram/ram-sidebar.webp");
--squares-and-triangles-background-repeat: repeat;
--squares-and-triangles-background-width-coef: 5;
--squares-and-triangles-background-height-coef: 15;
@@ -217,7 +257,7 @@ body {
--color-accent-deep: var(--color-indigo-800);
--color-main-dark-hard: #343b58;
--color-main-dark-medium: #414868;
- --color-main-dark-soft: #6c6e75;
+ --color-main-dark-soft: #6c6e75;
--color-main-light-hard: #e3e6ff;
--color-main-light-medium: #d1d6ff;
--color-main-light-soft: #c3caff;
@@ -240,16 +280,18 @@ body {
--squares-and-triangles-background-repeat: repeat;
--squares-and-triangles-background-width-coef: 5;
--squares-and-triangles-background-height-coef: 5;
- --split-left-background: url('https://storage.yandexcloud.kz/sayauz-static/themes/lilac/split-left.webp');
- --split-right-background: url('https://storage.yandexcloud.kz/sayauz-static/themes/lilac/split-right.webp');
+ --split-left-background: url("https://storage.yandexcloud.kz/sayauz-static/themes/lilac/split-left.webp");
+ --split-right-background: url("https://storage.yandexcloud.kz/sayauz-static/themes/lilac/split-right.webp");
}
-a, .linklike {
+a,
+.linklike {
color: var(--color-main-medium) !important;
text-decoration: underline;
}
-a:hover, .linklike:hover {
+a:hover,
+.linklike:hover {
color: var(--color-main-soft) !important;
}
@@ -269,7 +311,7 @@ a:hover, .linklike:hover {
.crossable.disabled::before,
.crossable.htmx-request::before {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 0;
@@ -315,10 +357,18 @@ form.crossable.htmx-request input {
.text-sidebar {
color: var(--color-main-dark-soft);
- text-shadow: -0.2rem 0 var(--color-main-dark-hard), 0 -0.2rem var(--color-main-dark-hard), 0.2rem 0rem var(--color-main-light-soft), 0 0.2rem var(--color-main-light-soft);
+ text-shadow:
+ -0.2rem 0 var(--color-main-dark-hard),
+ 0 -0.2rem var(--color-main-dark-hard),
+ 0.2rem 0rem var(--color-main-light-soft),
+ 0 0.2rem var(--color-main-light-soft);
-webkit-text-stroke-color: var(--color-sidebar-stroke);
-webkit-text-stroke-width: 0.1rem;
- background: linear-gradient(135deg, color-mix(in srgb, var(--color-main-light-soft) 20%, transparent), color-mix(in srgb, var(--color-main-dark-soft) 20%, transparent));
+ background: linear-gradient(
+ 135deg,
+ color-mix(in srgb, var(--color-main-light-soft) 20%, transparent),
+ color-mix(in srgb, var(--color-main-dark-soft) 20%, transparent)
+ );
}
.text-secondary {
@@ -336,11 +386,15 @@ form.crossable.htmx-request input {
.bg-sidebar {
background-image: var(--squares-and-triangles-background);
background-repeat: var(--squares-and-triangles-background-repeat);
- background-size: calc(var(--squares-and-triangles-background-width-coef) * 1rem) calc(var(--squares-and-triangles-background-height-coef) * 1rem);
+ background-size: calc(
+ var(--squares-and-triangles-background-width-coef) * 1rem
+ )
+ calc(var(--squares-and-triangles-background-height-coef) * 1rem);
}
.inset-shadow {
- box-shadow: inset 0dvh 1dvh 1dvh -1dvh rgba(75, 81, 58, 0.5),
+ box-shadow:
+ inset 0dvh 1dvh 1dvh -1dvh rgba(75, 81, 58, 0.5),
inset 1dvh 0dvh 1dvh -1dvh rgba(75, 81, 58, 0.5),
inset -1dvh 0dvh 1dvh -1dvh rgba(75, 81, 58, 0.5),
inset 0dvh -0.5dvh rgba(75, 81, 58, 0.5);
@@ -402,7 +456,7 @@ form.crossable.htmx-request input {
}
.theme-icon.active::after {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 0;
@@ -417,7 +471,8 @@ form.crossable.htmx-request input {
position: relative;
background: color-mix(in srgb, var(--color-main-soft) 75%, transparent);
box-shadow: 0rem 0rem 1rem var(--color-main-hard);
- border: 0.5rem solid color-mix(in srgb, var(--color-main-soft) 90%, transparent);
+ border: 0.5rem solid
+ color-mix(in srgb, var(--color-main-soft) 90%, transparent);
backdrop-filter: blur(2px);
top: 35%;
left: 35%;
@@ -433,7 +488,11 @@ form.crossable.htmx-request input {
left: 0;
width: 100%;
height: 100%;
- background: linear-gradient(135deg, var(--color-main-light-hard), var(--color-main-dark-hard));
+ background: linear-gradient(
+ 135deg,
+ var(--color-main-light-hard),
+ var(--color-main-dark-hard)
+ );
opacity: 0.2;
z-index: 10;
content: "";
@@ -456,14 +515,16 @@ form.crossable.htmx-request input {
--border-size: 0.5rem;
}
-.themed-button:active, .themed-button.active {
+.themed-button:active,
+.themed-button.active {
border-top: var(--border-size) solid var(--color-main-dark-hard);
border-left: var(--border-size) solid var(--color-main-dark-hard);
border-bottom: var(--border-size) solid var(--color-main-light-hard);
border-right: var(--border-size) solid var(--color-main-light-hard);
}
-.themed-button:active > *, .themed-button.active > * {
+.themed-button:active > *,
+.themed-button.active > * {
transform: translateY(calc(var(--border-size) / 2));
}
@@ -471,7 +532,10 @@ form.crossable.htmx-request input {
--border-size: 0.25rem;
background-image: var(--squares-and-triangles-background);
background-repeat: var(--squares-and-triangles-background-repeat);
- background-size: calc(var(--squares-and-triangles-background-width-coef) * 0.9rem) calc(var(--squares-and-triangles-background-height-coef) * 0.9rem);
+ background-size: calc(
+ var(--squares-and-triangles-background-width-coef) * 0.9rem
+ )
+ calc(var(--squares-and-triangles-background-height-coef) * 0.9rem);
}
.themed-button.themed-button-like {
@@ -484,7 +548,7 @@ form.crossable.htmx-request input {
}
.custom-svg-marker svg {
- filter: drop-shadow(2px 2px 2px rgba(0,0,0,0.3));
+ filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.3));
transition: transform 0.2s;
}
@@ -582,7 +646,8 @@ form.crossable.htmx-request input {
}
@container main (width >= 76rem) {
- .grid-item, .grid-sizer {
+ .grid-item,
+ .grid-sizer {
width: 18rem;
}
@@ -606,12 +671,20 @@ form.crossable.htmx-request input {
}
.goverlay {
- background: color-mix(in srgb, var(--color-background-light) 50%, transparent) !important;
+ background: color-mix(
+ in srgb,
+ var(--color-background-light) 50%,
+ transparent
+ ) !important;
backdrop-filter: blur(1rem);
}
.glightbox-clean .gslide-description {
- background: color-mix(in srgb, var(--color-background-dark) 50%, transparent) !important;
+ background: color-mix(
+ in srgb,
+ var(--color-background-dark) 50%,
+ transparent
+ ) !important;
backdrop-filter: blur(1rem);
}
diff --git a/views/layouts/general-page.html b/views/layouts/general-page.html
index 2f949a3..0bd3454 100644
--- a/views/layouts/general-page.html
+++ b/views/layouts/general-page.html
@@ -1,470 +1,725 @@
-<!DOCTYPE html>
+<!doctype html>
<html lang="en">
-<head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- {{- range .Meta }}
- <meta {{with .Name}}name="{{.}}" {{end}}{{with .Property}}property="{{.}}" {{end}}{{with .Content}}content="{{.}}"{{end}}>
- {{- if eq .Property "og:description" }}
- <meta name="description" content="{{.Content}}">
- {{- end }}
- {{- if eq .Property "og:url" }}
- <link rel="canonical" href="{{.Content}}">
- {{- end }}
- {{- end }}
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/fonts/fonts.css">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/fontawesome.min.css">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/brands.min.css">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/solid.min.css">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/libs/leaflet/1.9.4/leaflet.css">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/libs/glightbox/3.3.0/css/glightbox.min.css">
- <link rel="stylesheet" href="/output.css">
- {{- with .LinkedData }}
- <script type="application/ld+json">
- {{ . }}
- </script>
- {{- end }}
-</head>
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ {{- range .Meta }}
+ <meta
+ {{with
+ .Name}}name="{{.}}"
+ {{end}}{{with
+ .Property}}property="{{.}}"
+ {{end}}{{with
+ .Content}}content="{{.}}"
+ {{end}}
+ />
+ {{- if eq .Property "og:description" }}
+ <meta name="description" content="{{.Content}}" />
+ {{- end }} {{- if eq .Property "og:url" }}
+ <link rel="canonical" href="{{.Content}}" />
+ {{- end }} {{- end }}
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/fonts/fonts.css"
+ />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/fontawesome.min.css"
+ />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/brands.min.css"
+ />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/solid.min.css"
+ />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/libs/leaflet/1.9.4/leaflet.css"
+ />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/libs/glightbox/3.3.0/css/glightbox.min.css"
+ />
+ <link rel="stylesheet" href="/output.css" />
+ <link
+ rel="icon"
+ href="/favicon-light.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: light)"
+ />
+ <link
+ rel="icon"
+ href="/favicon-dark.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: dark)"
+ />
+ {{- with .LinkedData }}
+ <script type="application/ld+json">
+ {{ . }}
+ </script>
+ {{- end }}
+ </head>
-<body data-theme="ram" class="font-m-plus text-main-hard overflow-hidden bg-interlocked-hexagons h-dvh flex flex-row">
+ <body
+ data-theme="ram"
+ class="font-m-plus text-main-hard overflow-hidden bg-interlocked-hexagons h-dvh flex flex-row"
+ >
+ <script>
+ let map = null;
+ </script>
- <script>
- let map = null;
- </script>
+ <script>
+ function changeUrl(path, toAppend = false) {
+ const urlParams = new URLSearchParams(window.location.search);
+ newPathname = location.pathname.endsWith("/")
+ ? location.pathname.slice(0, -1)
+ : location.pathname;
+ while (path.slice(-3) == "/.." && toAppend) {
+ newPathname = newPathname.replace(/\/[^\/]+$/, "");
+ path = path.slice(0, -3);
+ }
+ const newPath = toAppend ? `${newPathname}${path}` : `${path}`;
- <script>
- function changeUrl(path, toAppend = false) {
- const urlParams = new URLSearchParams(window.location.search);
- newPathname = location.pathname.endsWith('/') ? location.pathname.slice(0, -1) : location.pathname;
- while (path.slice(-3) == '/..' && toAppend) {
- newPathname = newPathname.replace(/\/[^\/]+$/, '');
- path = path.slice(0, -3);
+ history.pushState(
+ {},
+ "",
+ `${newPath}${urlParams.entries.length == 0 ? "" : "?" + urlParams.toString()}`,
+ );
+ window.dispatchEvent(new Event("popstate"));
+ return false;
}
- const newPath = toAppend ? `${newPathname}${path}` : `${path}`;
-
- history.pushState({}, '', `${newPath}${urlParams.entries.length == 0 ? '' : '?' + urlParams.toString()}`);
- window.dispatchEvent(new Event('popstate'));
- return false;
- };
- function convertRemToPixels(rem) {
- return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
- }
- </script>
+ function convertRemToPixels(rem) {
+ return (
+ rem *
+ parseFloat(
+ getComputedStyle(document.documentElement).fontSize,
+ )
+ );
+ }
+ </script>
- <script src="{{ .StaticStorageBaseUrl }}/libs/glightbox/3.3.0/js/glightbox.min.js"></script>
+ <script src="{{ .StaticStorageBaseUrl }}/libs/glightbox/3.3.0/js/glightbox.min.js"></script>
- <script>
- function sfc32(a, b, c, d) {
- return function() {
- a |= 0; b |= 0; c |= 0; d |= 0;
- let t = (a + b | 0) + d | 0;
- d = d + 1 | 0;
- a = b ^ b >>> 9;
- b = c + (c << 3) | 0;
- c = (c << 21 | c >>> 11);
- c = c + t | 0;
- return (t >>> 0) / 4294967296;
+ <script>
+ function sfc32(a, b, c, d) {
+ return function () {
+ a |= 0;
+ b |= 0;
+ c |= 0;
+ d |= 0;
+ let t = (((a + b) | 0) + d) | 0;
+ d = (d + 1) | 0;
+ a = b ^ (b >>> 9);
+ b = (c + (c << 3)) | 0;
+ c = (c << 21) | (c >>> 11);
+ c = (c + t) | 0;
+ return (t >>> 0) / 4294967296;
+ };
}
- }
- function cyrb128(str) {
- let h1 = 1779033703, h2 = 3144134277,
- h3 = 1013904242, h4 = 2773480762;
- for (let i = 0, k; i < str.length; i++) {
- k = str.charCodeAt(i);
- h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
- h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
- h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
- h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
+ function cyrb128(str) {
+ let h1 = 1779033703,
+ h2 = 3144134277,
+ h3 = 1013904242,
+ h4 = 2773480762;
+ for (let i = 0, k; i < str.length; i++) {
+ k = str.charCodeAt(i);
+ h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
+ h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
+ h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
+ h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
+ }
+ h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);
+ h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);
+ h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);
+ h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);
+ ((h1 ^= h2 ^ h3 ^ h4), (h2 ^= h1), (h3 ^= h1), (h4 ^= h1));
+ return [h1 >>> 0, h2 >>> 0, h3 >>> 0, h4 >>> 0];
}
- h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);
- h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);
- h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);
- h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);
- h1 ^= (h2 ^ h3 ^ h4), h2 ^= h1, h3 ^= h1, h4 ^= h1;
- return [h1>>>0, h2>>>0, h3>>>0, h4>>>0];
- }
- var seed = cyrb128("{{ .Title }}");
- var rand = sfc32(seed[0], seed[1], seed[2], seed[3]);
+ var seed = cyrb128("{{ .Title }}");
+ var rand = sfc32(seed[0], seed[1], seed[2], seed[3]);
- function calculateVmin(percent) {
- const viewportWidth = window.innerWidth;
- const viewportHeight = window.innerHeight;
+ function calculateVmin(percent) {
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
- const smallerDimension = Math.min(viewportWidth, viewportHeight);
+ const smallerDimension = Math.min(
+ viewportWidth,
+ viewportHeight,
+ );
- const vminValue = (smallerDimension / 100) * percent;
+ const vminValue = (smallerDimension / 100) * percent;
- return vminValue;
- }
+ return vminValue;
+ }
- function switchThemeDecor(theme) {
- document.querySelectorAll('.theme-decor').forEach((e) => {
- e.remove();
- });
+ function switchThemeDecor(theme) {
+ document.querySelectorAll(".theme-decor").forEach((e) => {
+ e.remove();
+ });
- if (theme == "" || typeof theme == "undefined") {
- theme = document.body.getAttribute('data-theme');
- }
+ if (theme == "" || typeof theme == "undefined") {
+ theme = document.body.getAttribute("data-theme");
+ }
- vmin = calculateVmin(1);
- var clWidth = document.documentElement.clientWidth;
- var clHeight = document.documentElement.clientHeight;
+ vmin = calculateVmin(1);
+ var clWidth = document.documentElement.clientWidth;
+ var clHeight = document.documentElement.clientHeight;
- switch (theme) {
- case "olive": break;
- case "lettuce": break;
- case "night":
- for (i = 0; i < 25; i++) {
- let star = document.createElement("div");
- star.append("*");
- star.classList.add("night-star", "theme-decor", "z-0", "absolute");
- const x = Math.floor(rand() * clWidth);
- const y = Math.floor(rand() * clHeight * 0.8);
- const rot = rand() * 90;
- const animDuration = (rand() * 10) + 3;
- const sz = Math.floor(rand() * 8) + 12;
- star.style.transform = `translateX(${x}px) translateY(${y}px) rotate(${rot}deg)`;
- star.style.animationDuration = `${animDuration}s`;
- star.style.fontSize = `${sz}px`;
- document.body.append(star);
- }
- break;
- case "ram":
- const frameCenters = new Array(4);
- for (i = 1; i <= 4; i++) {
- let frame = document.createElement("img");
- frame.src = `{{ .StaticStorageBaseUrl }}/themes/ram/ram-frame${i}.webp`;
- frame.classList.add("ram-frame", "theme-decor", "z-0", "absolute");
- let x, y;
- outerLoop:
- while (true) {
- x = Math.floor(rand() * clWidth - 20*vmin);
- y = Math.floor(rand() * clHeight - 20*vmin);
- for (j = 0; j < i-1; j++) {
- const xd = frameCenters[j].x - x;
- const yd = frameCenters[j].y - y;
- if (Math.sqrt(xd*xd + yd*yd) < 30*vmin) {
- continue outerLoop;
+ switch (theme) {
+ case "olive":
+ break;
+ case "lettuce":
+ break;
+ case "night":
+ for (i = 0; i < 25; i++) {
+ let star = document.createElement("div");
+ star.append("*");
+ star.classList.add(
+ "night-star",
+ "theme-decor",
+ "z-0",
+ "absolute",
+ );
+ const x = Math.floor(rand() * clWidth);
+ const y = Math.floor(rand() * clHeight * 0.8);
+ const rot = rand() * 90;
+ const animDuration = rand() * 10 + 3;
+ const sz = Math.floor(rand() * 8) + 12;
+ star.style.transform = `translateX(${x}px) translateY(${y}px) rotate(${rot}deg)`;
+ star.style.animationDuration = `${animDuration}s`;
+ star.style.fontSize = `${sz}px`;
+ document.body.append(star);
+ }
+ break;
+ case "ram":
+ const frameCenters = new Array(4);
+ for (i = 1; i <= 4; i++) {
+ let frame = document.createElement("img");
+ frame.src = `{{ .StaticStorageBaseUrl }}/themes/ram/ram-frame${i}.webp`;
+ frame.classList.add(
+ "ram-frame",
+ "theme-decor",
+ "z-0",
+ "absolute",
+ );
+ let x, y;
+ outerLoop: while (true) {
+ x = Math.floor(rand() * clWidth - 20 * vmin);
+ y = Math.floor(rand() * clHeight - 20 * vmin);
+ for (j = 0; j < i - 1; j++) {
+ const xd = frameCenters[j].x - x;
+ const yd = frameCenters[j].y - y;
+ if (
+ Math.sqrt(xd * xd + yd * yd) <
+ 30 * vmin
+ ) {
+ continue outerLoop;
+ }
}
+ break;
}
- break;
+ frameCenters[i - 1] = { x: x, y: y };
+ const rot = rand() * 90 - 45;
+ frame.style.transform = `translateX(${x}px) translateY(${y}px) rotate(${rot}deg)`;
+ document.body.append(frame);
}
- frameCenters[i-1] = {x: x, y: y};
- const rot = rand() * 90 - 45;
- frame.style.transform = `translateX(${x}px) translateY(${y}px) rotate(${rot}deg)`;
- document.body.append(frame);
- }
- break;
- case "lilac": break;
+ break;
+ case "lilac":
+ break;
+ }
}
- }
- function switchTheme(theme) {
- if (theme == "" || typeof theme == "undefined") {
- const currentTheme = document.body.getAttribute('data-theme');
- switch (currentTheme) {
- case "olive": theme = "lettuce"; break;
- case "lettuce": theme = "night"; break;
- case "night": theme = "ram"; break;
- case "ram": theme = "lilac"; break;
- case "lilac": theme = "olive"; break;
+ function switchTheme(theme) {
+ if (theme == "" || typeof theme == "undefined") {
+ const currentTheme =
+ document.body.getAttribute("data-theme");
+ switch (currentTheme) {
+ case "olive":
+ theme = "lettuce";
+ break;
+ case "lettuce":
+ theme = "night";
+ break;
+ case "night":
+ theme = "ram";
+ break;
+ case "ram":
+ theme = "lilac";
+ break;
+ case "lilac":
+ theme = "olive";
+ break;
+ }
}
+ localStorage.setItem("theme", theme);
+ document.body.setAttribute("data-theme", theme);
+ switchThemeDecor(theme);
}
- localStorage.setItem('theme', theme);
- document.body.setAttribute('data-theme', theme);
- switchThemeDecor(theme);
- }
- const savedTheme = localStorage.getItem('theme') || 'lilac';
- switchTheme(savedTheme);
- </script>
+ const savedTheme = localStorage.getItem("theme") || "lilac";
+ switchTheme(savedTheme);
+ </script>
- <div id="general-page-top-embeds" class="flex"
- hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </div>
- <div id="general-page-top-embeds-trigger" hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-top-embeds" hx-swap="innerHTML"></div>
+ <div
+ id="general-page-top-embeds"
+ class="flex"
+ hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="load"
+ hx-target="this"
+ hx-swap="innerHTML"
+ ></div>
+ <div
+ id="general-page-top-embeds-trigger"
+ hx-get="/api/v1/general-page/top-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="popstate from:window"
+ hx-target="#general-page-top-embeds"
+ hx-swap="innerHTML"
+ ></div>
- <script>
- const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
- </script>
+ <script>
+ const clientTimeZone =
+ Intl.DateTimeFormat().resolvedOptions().timeZone;
+ </script>
- <div class="grow bg-split-left"></div>
+ <div class="grow bg-split-left"></div>
- <div class="flex flex-col sm:flex-row">
- <div id="sidebar" class="bg-sidebar flex
- flex-row sticky w-dvw h-fit xs:w-[90dvw]
- sm:left-0 sm:flex-col sm:fixed sm:w-fit
- z-20 shadow-[0_0_1rem_black]">
- <nav aria-label="Main navigation" class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20">
- <a onclick="return changeUrl('/..', true);" href="../" id="sidebar-back-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
- <i class="fas fa-circle-left flex faw-18 h-18 content-center text-center text-sidebar"></i>
- </a>
- <a onclick="return changeUrl('/{{ .Lang }}');" href="/{{ .Lang }}" id="sidebar-home-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
- <i class="fas fa-home flex faw-18 h-18 content-center text-center text-sidebar"></i>
- </a>
- <a onclick="return changeUrl('/{{ .Lang }}/blog');" href="/{{ .Lang }}/blog" id="sidebar-blog-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
- <i class="fas fa-search flex faw-18 h-18 content-center text-center text-sidebar"></i>
- </a>
- <a href="/{{ .Lang }}/map" id="sidebar-map-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
- <i class="fas fa-map flex faw-18 h-18 content-center text-center text-sidebar"></i>
- </a>
- <div id="toolbar-theme-button" onclick="toggleThemeWheel();" class="themed-button themed-button-sidebar w-fit h-fit" draggable="false">
- <i id="toolbar-theme-button-content" class="fas fa-swatchbook flex faw-18 h-18 content-center text-center text-sidebar"></i>
+ <div class="flex flex-col sm:flex-row">
+ <div
+ id="sidebar"
+ class="bg-sidebar flex flex-row sticky w-dvw h-fit xs:w-[90dvw] sm:left-0 sm:flex-col sm:fixed sm:w-fit z-20 shadow-[0_0_1rem_black]"
+ >
+ <nav
+ aria-label="Main navigation"
+ class="text-[3rem] flex flex-row sm:flex-col gap-0 relative z-20"
+ >
+ <a
+ onclick="return changeUrl('/..', true);"
+ href="../"
+ id="sidebar-back-button"
+ class="themed-button themed-button-sidebar w-fit h-fit hidden"
+ draggable="false"
+ >
+ <i
+ class="fas fa-circle-left flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </a>
+ <a
+ onclick="return changeUrl('/{{ .Lang }}');"
+ href="/{{ .Lang }}"
+ id="sidebar-home-button"
+ class="themed-button themed-button-sidebar w-fit h-fit hidden"
+ draggable="false"
+ >
+ <i
+ class="fas fa-home flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </a>
+ <a
+ onclick="return changeUrl('/{{ .Lang }}/blog');"
+ href="/{{ .Lang }}/blog"
+ id="sidebar-blog-button"
+ class="themed-button themed-button-sidebar w-fit h-fit hidden"
+ draggable="false"
+ >
+ <i
+ class="fas fa-search flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </a>
+ <a
+ href="/{{ .Lang }}/map"
+ id="sidebar-map-button"
+ class="themed-button themed-button-sidebar w-fit h-fit hidden"
+ draggable="false"
+ >
+ <i
+ class="fas fa-map flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </a>
+ <div
+ id="toolbar-theme-button"
+ onclick="toggleThemeWheel()"
+ class="themed-button themed-button-sidebar w-fit h-fit"
+ draggable="false"
+ >
+ <i
+ id="toolbar-theme-button-content"
+ class="fas fa-swatchbook flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </div>
+ <a
+ onclick="return changeUrl('/{{ .Lang }}/user');"
+ href="/{{ .Lang }}/user"
+ id="sidebar-user-button"
+ class="themed-button themed-button-sidebar w-fit h-fit hidden"
+ draggable="false"
+ >
+ <i
+ class="fas fa-user flex faw-18 h-18 content-center text-center text-sidebar"
+ ></i>
+ </a>
+ </nav>
+ <div class="theme-wheel" id="theme-wheel">
+ <div class="theme-icon" data-theme="olive"></div>
+ <div class="theme-icon" data-theme="lettuce"></div>
+ <div class="theme-icon" data-theme="night"></div>
+ <div class="theme-icon" data-theme="ram"></div>
+ <div class="theme-icon" data-theme="lilac"></div>
+ <div class="theme-pin"></div>
</div>
- <a onclick="return changeUrl('/{{ .Lang }}/user');" href="/{{ .Lang }}/user" id="sidebar-user-button" class="themed-button themed-button-sidebar w-fit h-fit hidden" draggable="false">
- <i class="fas fa-user flex faw-18 h-18 content-center text-center text-sidebar"></i>
- </a>
- </nav>
- <div class="theme-wheel" id="theme-wheel">
- <div class="theme-icon" data-theme="olive"></div>
- <div class="theme-icon" data-theme="lettuce"></div>
- <div class="theme-icon" data-theme="night"></div>
- <div class="theme-icon" data-theme="ram"></div>
- <div class="theme-icon" data-theme="lilac"></div>
- <div class="theme-pin"></div>
- </div>
- <script>
- sidebarHomeButton = document.getElementById("sidebar-home-button");
- sidebarMapButton = document.getElementById("sidebar-map-button");
- sidebarBlogButton = document.getElementById("sidebar-blog-button");
- sidebarBackButton = document.getElementById("sidebar-back-button");
- sidebarUserButton = document.getElementById("sidebar-user-button");
+ <script>
+ sidebarHomeButton = document.getElementById(
+ "sidebar-home-button",
+ );
+ sidebarMapButton =
+ document.getElementById("sidebar-map-button");
+ sidebarBlogButton = document.getElementById(
+ "sidebar-blog-button",
+ );
+ sidebarBackButton = document.getElementById(
+ "sidebar-back-button",
+ );
+ sidebarUserButton = document.getElementById(
+ "sidebar-user-button",
+ );
- function updateSidebar() {
- if (location.pathname == "" || location.pathname == "/") {
- sidebarHomeButton.classList.add('hidden');
- sidebarMapButton.classList.add('hidden');
- sidebarBlogButton.classList.add('hidden');
- sidebarBackButton.classList.add('hidden');
- sidebarUserButton.classList.add('hidden');
- } else {
- sidebarHomeButton.classList.remove('hidden');
- sidebarMapButton.classList.remove('hidden');
- sidebarBlogButton.classList.remove('hidden');
- sidebarBackButton.classList.remove('hidden');
- sidebarUserButton.classList.remove('hidden');
- lang = location.pathname.split("/")[1];
- sidebarHomeButton.setAttribute('href', `/${lang}`);
- sidebarHomeButton.setAttribute('onclick', `return changeUrl('/${lang}', false);`);
- sidebarMapButton.setAttribute('href', `/${lang}/map`);
- sidebarBlogButton.setAttribute('href', `/${lang}/blog`);
- sidebarBlogButton.setAttribute('onclick', `return changeUrl('/${lang}/blog', false);`);
- sidebarUserButton.setAttribute('href', `/${lang}/user`);
- sidebarUserButton.setAttribute('onclick', `return changeUrl('/${lang}/user', false);`);
+ function updateSidebar() {
+ if (
+ location.pathname == "" ||
+ location.pathname == "/"
+ ) {
+ sidebarHomeButton.classList.add("hidden");
+ sidebarMapButton.classList.add("hidden");
+ sidebarBlogButton.classList.add("hidden");
+ sidebarBackButton.classList.add("hidden");
+ sidebarUserButton.classList.add("hidden");
+ } else {
+ sidebarHomeButton.classList.remove("hidden");
+ sidebarMapButton.classList.remove("hidden");
+ sidebarBlogButton.classList.remove("hidden");
+ sidebarBackButton.classList.remove("hidden");
+ sidebarUserButton.classList.remove("hidden");
+ lang = location.pathname.split("/")[1];
+ sidebarHomeButton.setAttribute("href", `/${lang}`);
+ sidebarHomeButton.setAttribute(
+ "onclick",
+ `return changeUrl('/${lang}', false);`,
+ );
+ sidebarMapButton.setAttribute(
+ "href",
+ `/${lang}/map`,
+ );
+ sidebarBlogButton.setAttribute(
+ "href",
+ `/${lang}/blog`,
+ );
+ sidebarBlogButton.setAttribute(
+ "onclick",
+ `return changeUrl('/${lang}/blog', false);`,
+ );
+ sidebarUserButton.setAttribute(
+ "href",
+ `/${lang}/user`,
+ );
+ sidebarUserButton.setAttribute(
+ "onclick",
+ `return changeUrl('/${lang}/user', false);`,
+ );
+ }
}
- }
- window.addEventListener("popstate", updateSidebar);
- window.addEventListener("load", updateSidebar, {once: true});
- </script>
- </div>
+ window.addEventListener("popstate", updateSidebar);
+ window.addEventListener("load", updateSidebar, {
+ once: true,
+ });
+ </script>
+ </div>
- <div class="bg-paper bg-background-dark @container/main flex z-10 w-dvw xs:w-[90dvw] sm:w-[85dvw] md:w-[80dvw] lg:w-[75dvw] xl:w-[70dvw] 2xl:w-[60dvw] 3xl:w-[50dvw] grow-0 h-[calc(100dvh-5rem)] sm:h-dvh shadow-[0_0_1rem_black]">
- <div class="bg-paper bg-background-dark border-r-2 border-dashed border-main-hard"></div>
+ <div
+ class="bg-paper bg-background-dark @container/main flex z-10 w-dvw xs:w-[90dvw] sm:w-[85dvw] md:w-[80dvw] lg:w-[75dvw] xl:w-[70dvw] 2xl:w-[60dvw] 3xl:w-[50dvw] grow-0 h-[calc(100dvh-5rem)] sm:h-dvh shadow-[0_0_1rem_black]"
+ >
+ <div
+ class="bg-paper bg-background-dark border-r-2 border-dashed border-main-hard"
+ ></div>
- <div class="max-h-full max-w-full flex flex-col grow bg-paper bg-background-dark relative pt-4 ml-8 pr-4">
- <header id="general-page-header" class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
- hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </header>
- <div id="general-page-header-trigger" hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-header" hx-swap="innerHTML"></div>
+ <div
+ class="max-h-full max-w-full flex flex-col grow bg-paper bg-background-dark relative pt-4 ml-8 pr-4"
+ >
+ <header
+ id="general-page-header"
+ class="max-xs:hidden [@media(max-height:32rem)]:hidden flex flex-col basis-8"
+ hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="load"
+ hx-target="this"
+ hx-swap="innerHTML"
+ ></header>
+ <div
+ id="general-page-header-trigger"
+ hx-get="/api/v1/general-page/header{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="popstate from:window"
+ hx-target="#general-page-header"
+ hx-swap="innerHTML"
+ ></div>
- <hr class="max-xs:hidden [@media(max-height:32rem)]:hidden border-t-4 border-dotted border-main-hard mb-2">
+ <hr
+ class="max-xs:hidden [@media(max-height:32rem)]:hidden border-t-4 border-dotted border-main-hard mb-2"
+ />
- <main id="general-page-body" class="relative flex flex-col grow overflow-y-auto"
- hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </main>
- <div id="general-page-body-trigger" hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-body" hx-swap="innerHTML"></div>
+ <main
+ id="general-page-body"
+ class="relative flex flex-col grow overflow-y-auto"
+ hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="load"
+ hx-target="this"
+ hx-swap="innerHTML"
+ ></main>
+ <div
+ id="general-page-body-trigger"
+ hx-get="/api/v1/general-page/body{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="popstate from:window"
+ hx-target="#general-page-body"
+ hx-swap="innerHTML"
+ ></div>
- <footer id="general-page-footer" class="flex flex-row basis-4 my-1"
- hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </footer>
- <div id="general-page-footer-trigger" hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-footer" hx-swap="innerHTML"></div>
+ <footer
+ id="general-page-footer"
+ class="flex flex-row basis-4 my-1"
+ hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="load"
+ hx-target="this"
+ hx-swap="innerHTML"
+ ></footer>
+ <div
+ id="general-page-footer-trigger"
+ hx-get="/api/v1/general-page/footer{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="popstate from:window"
+ hx-target="#general-page-footer"
+ hx-swap="innerHTML"
+ ></div>
- <hr class="border-t-4 border-dotted border-main-hard mb-2">
- </div>
+ <hr
+ class="border-t-4 border-dotted border-main-hard mb-2"
+ />
+ </div>
- <div class="pr-[0.5dvw] bg-paper bg-background-dark shadow-2xl border-l-2 border-dotted border-main-hard"></div>
+ <div
+ class="pr-[0.5dvw] bg-paper bg-background-dark shadow-2xl border-l-2 border-dotted border-main-hard"
+ ></div>
+ </div>
</div>
- </div>
- <div class="grow bg-split-right"></div>
+ <div class="grow bg-split-right"></div>
- <script src="{{ .StaticStorageBaseUrl }}/libs/htmx/2.0.6/htmx.min.js"></script>
- <script src="{{ .StaticStorageBaseUrl }}/libs/leaflet/1.9.4/leaflet.js"></script>
- <script src="{{ .StaticStorageBaseUrl }}/libs/imagesloaded/5.0.0/imagesloaded.pkgd.min.js"></script>
- <script src="{{ .StaticStorageBaseUrl }}/libs/packery/3.0.0/dist/packery.pkgd.min.js"></script>
+ <script src="{{ .StaticStorageBaseUrl }}/libs/htmx/2.0.6/htmx.min.js"></script>
+ <script src="{{ .StaticStorageBaseUrl }}/libs/leaflet/1.9.4/leaflet.js"></script>
+ <script src="{{ .StaticStorageBaseUrl }}/libs/imagesloaded/5.0.0/imagesloaded.pkgd.min.js"></script>
+ <script src="{{ .StaticStorageBaseUrl }}/libs/packery/3.0.0/dist/packery.pkgd.min.js"></script>
- <script>
- // Enable fitWidth-like attribute for Packery. Source: https://codepen.io/desandro/pen/kVmLYz
- var __resetLayout = Packery.prototype._resetLayout;
- Packery.prototype._resetLayout = function() {
- __resetLayout.call( this );
- var parentSize = getSize( this.element.parentNode );
- var colW = this.columnWidth + this.gutter;
- this.fitWidth = Math.floor( ( parentSize.innerWidth + this.gutter ) / colW ) * colW;
- this.packer.width = this.fitWidth;
- this.packer.height = Number.POSITIVE_INFINITY;
- this.packer.reset();
- };
+ <script>
+ // Enable fitWidth-like attribute for Packery. Source: https://codepen.io/desandro/pen/kVmLYz
+ var __resetLayout = Packery.prototype._resetLayout;
+ Packery.prototype._resetLayout = function () {
+ __resetLayout.call(this);
+ var parentSize = getSize(this.element.parentNode);
+ var colW = this.columnWidth + this.gutter;
+ this.fitWidth =
+ Math.floor((parentSize.innerWidth + this.gutter) / colW) *
+ colW;
+ this.packer.width = this.fitWidth;
+ this.packer.height = Number.POSITIVE_INFINITY;
+ this.packer.reset();
+ };
- Packery.prototype._getContainerSize = function() {
- var emptyWidth = 0;
- for ( var i=0, len = this.packer.spaces.length; i < len; i++ ) {
- var space = this.packer.spaces[i];
- if ( space.y === 0 && space.height === Number.POSITIVE_INFINITY ) {
- emptyWidth += space.width;
+ Packery.prototype._getContainerSize = function () {
+ var emptyWidth = 0;
+ for (var i = 0, len = this.packer.spaces.length; i < len; i++) {
+ var space = this.packer.spaces[i];
+ if (
+ space.y === 0 &&
+ space.height === Number.POSITIVE_INFINITY
+ ) {
+ emptyWidth += space.width;
+ }
}
- }
- return {
- width: this.fitWidth - this.gutter - emptyWidth,
- height: this.maxY - this.gutter
+ return {
+ width: this.fitWidth - this.gutter - emptyWidth,
+ height: this.maxY - this.gutter,
+ };
};
- };
- Packery.prototype.needsResizeLayout = function() {
- return true;
- };
- </script>
+ Packery.prototype.needsResizeLayout = function () {
+ return true;
+ };
+ </script>
- <div id="general-page-bottom-embeds" class="flex"
- hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="load" hx-target="this" hx-swap="innerHTML">
- </div>
- <div id="general-page-bottom-embeds-trigger" hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}" hx-trigger="popstate from:window" hx-target="#general-page-bottom-embeds" hx-swap="innerHTML"></div>
+ <div
+ id="general-page-bottom-embeds"
+ class="flex"
+ hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="load"
+ hx-target="this"
+ hx-swap="innerHTML"
+ ></div>
+ <div
+ id="general-page-bottom-embeds-trigger"
+ hx-get="/api/v1/general-page/bottom-embeds{{ if .QueryString }}?{{ .QueryString }}{{ end }}"
+ hx-trigger="popstate from:window"
+ hx-target="#general-page-bottom-embeds"
+ hx-swap="innerHTML"
+ ></div>
- <script>
- const themeWheel = document.getElementById('theme-wheel');
- const themeButton = document.getElementById('toolbar-theme-button');
- const themeIcons = document.querySelectorAll('.theme-icon');
- const themeWheelRadius = convertRemToPixels(6);
+ <script>
+ const themeWheel = document.getElementById("theme-wheel");
+ const themeButton = document.getElementById("toolbar-theme-button");
+ const themeIcons = document.querySelectorAll(".theme-icon");
+ const themeWheelRadius = convertRemToPixels(6);
- themeIcons.forEach(icon => {
- if (icon.getAttribute('data-theme') == savedTheme) {
- icon.classList.add('active');
- }
- });
+ themeIcons.forEach((icon) => {
+ if (icon.getAttribute("data-theme") == savedTheme) {
+ icon.classList.add("active");
+ }
+ });
- function calculateVmax(percent) {
- const viewportWidth = window.innerWidth;
- const viewportHeight = window.innerHeight;
+ function calculateVmax(percent) {
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
- const largerDimension = Math.max(viewportWidth, viewportHeight);
+ const largerDimension = Math.max(viewportWidth, viewportHeight);
- const vmaxValue = (largerDimension / 100) * percent;
+ const vmaxValue = (largerDimension / 100) * percent;
- return vmaxValue;
- }
+ return vmaxValue;
+ }
- function positionThemeIcons() {
- const sliceAngle = 360 / themeIcons.length;
+ function positionThemeIcons() {
+ const sliceAngle = 360 / themeIcons.length;
- themeIcons.forEach((icon, index) => {
- const startAngle = index * sliceAngle;
- const endAngle = (index + 1) * sliceAngle;
+ themeIcons.forEach((icon, index) => {
+ const startAngle = index * sliceAngle;
+ const endAngle = (index + 1) * sliceAngle;
- const clipPath = createSliceClipPath(startAngle, endAngle, themeWheelRadius);
- icon.style.clipPath = clipPath;
- });
- }
+ const clipPath = createSliceClipPath(
+ startAngle,
+ endAngle,
+ themeWheelRadius,
+ );
+ icon.style.clipPath = clipPath;
+ });
+ }
+
+ function createSliceClipPath(startAngle, endAngle, radius) {
+ const centerX = radius;
+ const centerY = radius;
+
+ let points = `${centerX}px ${centerY}px`;
- function createSliceClipPath(startAngle, endAngle, radius) {
- const centerX = radius;
- const centerY = radius;
+ const segments = Math.max(
+ 2,
+ Math.ceil(Math.abs(endAngle - startAngle) / 5),
+ );
+ const angleStep = (endAngle - startAngle) / segments;
- let points = `${centerX}px ${centerY}px`;
+ for (let i = 0; i <= segments; i++) {
+ const angle =
+ ((startAngle + angleStep * i - 90) * Math.PI) / 180;
+ const x = centerX + Math.cos(angle) * radius;
+ const y = centerY + Math.sin(angle) * radius;
+ points += `, ${x}px ${y}px`;
+ }
- const segments = Math.max(2, Math.ceil(Math.abs(endAngle - startAngle) / 5));
- const angleStep = (endAngle - startAngle) / segments;
+ points += `, ${centerX}px ${centerY}px`;
- for (let i = 0; i <= segments; i++) {
- const angle = ((startAngle + angleStep * i - 90) * Math.PI) / 180;
- const x = centerX + Math.cos(angle) * radius;
- const y = centerY + Math.sin(angle) * radius;
- points += `, ${x}px ${y}px`;
+ return `polygon(${points})`;
}
- points += `, ${centerX}px ${centerY}px`;
-
- return `polygon(${points})`;
- }
+ function positionThemeWheel() {
+ const buttonRect = themeButton.getBoundingClientRect();
+ const buttonCenterX = buttonRect.left + buttonRect.width / 2;
+ const buttonCenterY = buttonRect.top + buttonRect.height / 2;
- function positionThemeWheel() {
- const buttonRect = themeButton.getBoundingClientRect();
- const buttonCenterX = buttonRect.left + buttonRect.width / 2;
- const buttonCenterY = buttonRect.top + buttonRect.height / 2;
+ const margin = 0;
- const margin = 0;
+ let wheelX = buttonCenterX - themeWheelRadius;
+ let wheelY = buttonCenterY - themeWheelRadius;
- let wheelX = buttonCenterX - themeWheelRadius;
- let wheelY = buttonCenterY - themeWheelRadius;
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
- const viewportWidth = window.innerWidth;
- const viewportHeight = window.innerHeight;
+ if (wheelX < margin) {
+ wheelX = margin;
+ } else if (
+ wheelX + themeWheelRadius * 2 >
+ viewportWidth - margin
+ ) {
+ wheelX = viewportWidth - themeWheelRadius * 2 - margin;
+ }
- if (wheelX < margin) {
- wheelX = margin;
- } else if (wheelX + (themeWheelRadius * 2) > viewportWidth - margin) {
- wheelX = viewportWidth - (themeWheelRadius * 2) - margin;
- }
+ if (wheelY < margin) {
+ wheelY = margin;
+ } else if (
+ wheelY + themeWheelRadius * 2 >
+ viewportHeight - margin
+ ) {
+ wheelY = viewportHeight - themeWheelRadius * 2 - margin;
+ }
- if (wheelY < margin) {
- wheelY = margin;
- } else if (wheelY + (themeWheelRadius * 2) > viewportHeight - margin) {
- wheelY = viewportHeight - (themeWheelRadius * 2) - margin;
+ themeWheel.style.left = wheelX + "px";
+ themeWheel.style.top = wheelY + "px";
}
- themeWheel.style.left = wheelX + 'px';
- themeWheel.style.top = wheelY + 'px';
- }
-
- function hideThemeWheel() {
- themeWheel.classList.remove('active');
- }
+ function hideThemeWheel() {
+ themeWheel.classList.remove("active");
+ }
- function showThemeWheel() {
- positionThemeWheel();
- positionThemeIcons();
- themeWheel.classList.add('active');
- }
+ function showThemeWheel() {
+ positionThemeWheel();
+ positionThemeIcons();
+ themeWheel.classList.add("active");
+ }
- function toggleThemeWheel() {
- if (themeWheel.classList.contains('active')) {
- hideThemeWheel();
- } else {
- showThemeWheel();
+ function toggleThemeWheel() {
+ if (themeWheel.classList.contains("active")) {
+ hideThemeWheel();
+ } else {
+ showThemeWheel();
+ }
}
- }
- themeIcons.forEach(icon => {
- icon.addEventListener('click', (e) => {
- e.stopPropagation();
- const theme = icon.getAttribute('data-theme');
- switchTheme(theme);
- themeIcons.forEach(icon => {
- icon.classList.remove('active');
- })
- icon.classList.add('active');
+ themeIcons.forEach((icon) => {
+ icon.addEventListener("click", (e) => {
+ e.stopPropagation();
+ const theme = icon.getAttribute("data-theme");
+ switchTheme(theme);
+ themeIcons.forEach((icon) => {
+ icon.classList.remove("active");
+ });
+ icon.classList.add("active");
+ });
});
- });
-
- themeWheel.addEventListener('mouseleave', hideThemeWheel);
- document.addEventListener('click', (e) => {
- if (!themeWheel.contains(e.target) && e.target !== themeButton && !e.target.classList.contains("toolbar-theme-button-content")) {
- hideThemeWheel();
- }
- });
- </script>
+ themeWheel.addEventListener("mouseleave", hideThemeWheel);
- <script>
- let decorResizeTimeout;
- window.addEventListener('resize', function() {
- clearTimeout(decorResizeTimeout);
- decorResizeTimeout = setTimeout(switchThemeDecor, 300);
- });
- </script>
+ document.addEventListener("click", (e) => {
+ if (
+ !themeWheel.contains(e.target) &&
+ e.target !== themeButton &&
+ !e.target.classList.contains("toolbar-theme-button-content")
+ ) {
+ hideThemeWheel();
+ }
+ });
+ </script>
-</body>
+ <script>
+ let decorResizeTimeout;
+ window.addEventListener("resize", function () {
+ clearTimeout(decorResizeTimeout);
+ decorResizeTimeout = setTimeout(switchThemeDecor, 300);
+ });
+ </script>
+ </body>
</html>
diff --git a/views/pages/global-map.html b/views/pages/global-map.html
index bb51131..ce9d5b1 100644
--- a/views/pages/global-map.html
+++ b/views/pages/global-map.html
@@ -15,8 +15,11 @@
/>
<meta property="og:type" content="site" />
<title>{{ .L.GlobalMap.Header }} // SAYA.UZ</title>
- <link rel="canonical" href="{{ .CanonicalEndpoint }}/{{ .Lang }}/map">
- <link rel="stylesheet" href="{{ .StaticStorageBaseUrl }}/fonts/fonts.css">
+ <link rel="canonical" href="{{ .CanonicalEndpoint }}/{{ .Lang }}/map" />
+ <link
+ rel="stylesheet"
+ href="{{ .StaticStorageBaseUrl }}/fonts/fonts.css"
+ />
<link
rel="stylesheet"
href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/fontawesome.min.css"
@@ -30,7 +33,19 @@
href="{{ .StaticStorageBaseUrl }}/libs/font-awesome/7.2.0/css/solid.min.css"
/>
{{ block "header" . }}{{ end }}
- <link rel="stylesheet" href="/output.css">
+ <link rel="stylesheet" href="/output.css" />
+ <link
+ rel="icon"
+ href="/favicon-light.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: light)"
+ />
+ <link
+ rel="icon"
+ href="/favicon-dark.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: dark)"
+ />
<link
rel="stylesheet"
href="{{ .StaticStorageBaseUrl }}/libs/leaflet/1.9.4/leaflet.css"
diff --git a/views/pages/unsubscribe-page.html b/views/pages/unsubscribe-page.html
index c9de473..a917746 100644
--- a/views/pages/unsubscribe-page.html
+++ b/views/pages/unsubscribe-page.html
@@ -4,6 +4,18 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex,nofollow" />
+ <link
+ rel="icon"
+ href="/favicon-light.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: light)"
+ />
+ <link
+ rel="icon"
+ href="/favicon-dark.svg"
+ type="image/svg+xml"
+ media="(prefers-color-scheme: dark)"
+ />
<title>{{ .L.UnsubscribePage.Header }} // SAYA.UZ</title>
<style>
.bg-paper {