diff --git a/index.html b/index.html index a38d208..f71584d 100644 --- a/index.html +++ b/index.html @@ -8,10 +8,10 @@ - -
+ +
@@ -55,6 +63,7 @@ + diff --git a/public/images/immich.png b/public/images/immich-dark.png similarity index 100% rename from public/images/immich.png rename to public/images/immich-dark.png diff --git a/public/images/immich-light.png b/public/images/immich-light.png new file mode 100644 index 0000000..35a6152 Binary files /dev/null and b/public/images/immich-light.png differ diff --git a/public/images/logo-dark.svg b/public/images/logo-dark.svg new file mode 100644 index 0000000..a70a58d --- /dev/null +++ b/public/images/logo-dark.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/nextcloud.png b/public/images/nextcloud-dark.png similarity index 100% rename from public/images/nextcloud.png rename to public/images/nextcloud-dark.png diff --git a/public/images/nextcloud-light.png b/public/images/nextcloud-light.png new file mode 100644 index 0000000..5b06c90 Binary files /dev/null and b/public/images/nextcloud-light.png differ diff --git a/public/images/vaultwarden-dark.png b/public/images/vaultwarden-dark.png new file mode 100644 index 0000000..19164ae Binary files /dev/null and b/public/images/vaultwarden-dark.png differ diff --git a/public/images/vaultwarden.png b/public/images/vaultwarden-light.png similarity index 100% rename from public/images/vaultwarden.png rename to public/images/vaultwarden-light.png diff --git a/public/images/zipline.png b/public/images/zipline-dark.png similarity index 100% rename from public/images/zipline.png rename to public/images/zipline-dark.png diff --git a/public/images/zipline-light.png b/public/images/zipline-light.png new file mode 100644 index 0000000..c52ca4f Binary files /dev/null and b/public/images/zipline-light.png differ diff --git a/public/js/cards.js b/public/js/cards.js index bec49d3..00a6776 100644 --- a/public/js/cards.js +++ b/public/js/cards.js @@ -31,10 +31,14 @@ const cards = [ ]; const services = document.getElementById("services"); -window.onload = function () { +function renderCards() { + const theme = document.getElementById("body").classList[0]; + services.innerHTML = ""; for (let index = 0; index < cards.length; index++) { + const image_name = cards[index].image.split(".")[0]; + const image_ext = cards[index].image.split(".")[1]; const template = ` - +
${cards[index].name}
@@ -65,4 +69,5 @@ window.onload = function () { services.appendChild(element); } -}; +} +window.onload = renderCards(); diff --git a/public/js/theme.js b/public/js/theme.js new file mode 100644 index 0000000..d5d705f --- /dev/null +++ b/public/js/theme.js @@ -0,0 +1,36 @@ +const bodyElement = document.getElementById("body"); +const logo = document.getElementById("logo"); +const themeToggle = document.getElementById("theme-toggle"); + +const setTheme = (theme) => { + bodyElement.classList.remove(theme == "light" ? "dark" : "light"); + bodyElement.classList.add(theme == "light" ? "light" : "dark"); + theme == "light" + ? (themeToggle.checked = false) + : (themeToggle.checked = true); + logo.src = `/public/images/logo-${theme}.svg`; + localStorage.setItem("theme", theme); +}; + +function updateTheme() { + let theme = localStorage.getItem("theme"); + console.log("updatingTheme", theme); + if (theme) { + setTheme(theme); + } else { + setTheme("light"); + } +} + +themeToggle.addEventListener("click", () => { + let theme = localStorage.getItem("theme"); + if (theme == "light") { + setTheme("dark"); + renderCards(); + } else { + setTheme("light"); + renderCards(); + } +}); + +updateTheme(); diff --git a/public/output.css b/public/output.css index 4b1a3c7..30d9a4d 100644 --- a/public/output.css +++ b/public/output.css @@ -1053,6 +1053,18 @@ input:checked + .toggle-bg { } } +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + .visible { visibility: visible; } @@ -1170,6 +1182,18 @@ input:checked + .toggle-bg { margin-top: 1.5rem; } +.ms-3 { + margin-inline-start: 0.75rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mr-4 { + margin-right: 1rem; +} + .block { display: block; } @@ -1250,20 +1274,8 @@ input:checked + .toggle-bg { width: 100%; } -.w-auto { - width: auto; -} - -.w-\[25\%\] { - width: 25%; -} - -.w-\[50\%\] { - width: 50%; -} - -.w-\[100\%\] { - width: 100%; +.w-11 { + width: 2.75rem; } .max-w-\[1440px\] { @@ -1392,6 +1404,14 @@ input:checked + .toggle-bg { gap: 0.5rem; } +.gap-4 { + gap: 1rem; +} + +.gap-6 { + gap: 1.5rem; +} + .space-x-2 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.5rem * var(--tw-space-x-reverse)); @@ -1406,14 +1426,14 @@ input:checked + .toggle-bg { white-space: pre; } -.rounded-lg { - border-radius: 0.5rem; -} - .rounded-full { border-radius: 9999px; } +.rounded-lg { + border-radius: 0.5rem; +} + .rounded-e-lg { border-start-end-radius: 0.5rem; border-end-end-radius: 0.5rem; @@ -1496,15 +1516,6 @@ input:checked + .toggle-bg { background-color: rgb(17 24 39 / 0.5); } -.bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.bg-white\/50 { - background-color: rgb(255 255 255 / 0.5); -} - .bg-green-500 { --tw-bg-opacity: 1; background-color: rgb(14 159 110 / var(--tw-bg-opacity)); @@ -1515,21 +1526,25 @@ input:checked + .toggle-bg { background-color: rgb(224 36 36 / var(--tw-bg-opacity)); } -.bg-yellow-400 { - --tw-bg-opacity: 1; - background-color: rgb(227 160 8 / var(--tw-bg-opacity)); -} - -.bg-slate-200 { - --tw-bg-opacity: 1; - background-color: rgb(226 232 240 / var(--tw-bg-opacity)); -} - .bg-slate-50 { --tw-bg-opacity: 1; background-color: rgb(248 250 252 / var(--tw-bg-opacity)); } +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.bg-white\/50 { + background-color: rgb(255 255 255 / 0.5); +} + +.bg-yellow-400 { + --tw-bg-opacity: 1; + background-color: rgb(227 160 8 / var(--tw-bg-opacity)); +} + .object-cover { -o-object-fit: cover; object-fit: cover; @@ -1560,6 +1575,11 @@ input:checked + .toggle-bg { padding-right: 0.5rem; } +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + .px-5 { padding-left: 1.25rem; padding-right: 1.25rem; @@ -1580,11 +1600,6 @@ input:checked + .toggle-bg { padding-bottom: 0.75rem; } -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - .py-4 { padding-top: 1rem; padding-bottom: 1rem; @@ -1693,11 +1708,6 @@ input:checked + .toggle-bg { color: rgb(255 255 255 / var(--tw-text-opacity)); } -.text-gray-600 { - --tw-text-opacity: 1; - color: rgb(75 85 99 / var(--tw-text-opacity)); -} - .opacity-0 { opacity: 0; } @@ -1755,6 +1765,65 @@ input:checked + .toggle-bg { transition-timing-function: cubic-bezier(0, 0, 0.2, 1); } +.after\:absolute::after { + content: var(--tw-content); + position: absolute; +} + +.after\:start-\[2px\]::after { + content: var(--tw-content); + inset-inline-start: 2px; +} + +.after\:top-\[2px\]::after { + content: var(--tw-content); + top: 2px; +} + +.after\:h-5::after { + content: var(--tw-content); + height: 1.25rem; +} + +.after\:w-5::after { + content: var(--tw-content); + width: 1.25rem; +} + +.after\:rounded-full::after { + content: var(--tw-content); + border-radius: 9999px; +} + +.after\:border::after { + content: var(--tw-content); + border-width: 1px; +} + +.after\:border-gray-300::after { + content: var(--tw-content); + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.after\:bg-white::after { + content: var(--tw-content); + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.after\:transition-all::after { + content: var(--tw-content); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.after\:content-\[\'\'\]::after { + --tw-content: ''; + content: var(--tw-content); +} + .hover\:border-gray-300:hover { --tw-border-opacity: 1; border-color: rgb(209 213 219 / var(--tw-border-opacity)); @@ -1835,132 +1904,40 @@ input:checked + .toggle-bg { --tw-ring-color: rgb(229 231 235 / var(--tw-ring-opacity)); } -.dark\:border-blue-500:is(.dark *) { - --tw-border-opacity: 1; - border-color: rgb(63 131 248 / var(--tw-border-opacity)); -} - -.dark\:border-gray-600:is(.dark *) { - --tw-border-opacity: 1; - border-color: rgb(75 85 99 / var(--tw-border-opacity)); -} - -.dark\:border-gray-700:is(.dark *) { - --tw-border-opacity: 1; - border-color: rgb(55 65 81 / var(--tw-border-opacity)); -} - -.dark\:border-transparent:is(.dark *) { - border-color: transparent; -} - -.dark\:bg-blue-600:is(.dark *) { +.peer:checked ~ .peer-checked\:bg-blue-600 { --tw-bg-opacity: 1; background-color: rgb(28 100 242 / var(--tw-bg-opacity)); } -.dark\:bg-gray-600:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +.peer:checked ~ .peer-checked\:after\:translate-x-full::after { + content: var(--tw-content); + --tw-translate-x: 100%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.dark\:bg-gray-700:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +.peer:checked ~ .peer-checked\:after\:border-white::after { + content: var(--tw-content); + --tw-border-opacity: 1; + border-color: rgb(255 255 255 / var(--tw-border-opacity)); } -.dark\:bg-gray-800:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +.peer:focus ~ .peer-focus\:outline-none { + outline: 2px solid transparent; + outline-offset: 2px; } -.dark\:bg-gray-800\/50:is(.dark *) { - background-color: rgb(31 41 55 / 0.5); +.peer:focus ~ .peer-focus\:ring-4 { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } -.dark\:bg-gray-900\/80:is(.dark *) { - background-color: rgb(17 24 39 / 0.8); -} - -.dark\:text-blue-500:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(63 131 248 / var(--tw-text-opacity)); -} - -.dark\:text-gray-400:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(156 163 175 / var(--tw-text-opacity)); -} - -.dark\:text-white:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.dark\:hover\:bg-blue-700:hover:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(26 86 219 / var(--tw-bg-opacity)); -} - -.dark\:hover\:bg-gray-600:hover:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(75 85 99 / var(--tw-bg-opacity)); -} - -.dark\:hover\:bg-gray-700:hover:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(55 65 81 / var(--tw-bg-opacity)); -} - -.dark\:hover\:bg-gray-800:hover:is(.dark *) { - --tw-bg-opacity: 1; - background-color: rgb(31 41 55 / var(--tw-bg-opacity)); -} - -.dark\:hover\:text-blue-500:hover:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(63 131 248 / var(--tw-text-opacity)); -} - -.dark\:hover\:text-gray-300:hover:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(209 213 219 / var(--tw-text-opacity)); -} - -.dark\:hover\:text-white:hover:is(.dark *) { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.dark\:focus\:ring-blue-800:focus:is(.dark *) { +.peer:focus ~ .peer-focus\:ring-blue-300 { --tw-ring-opacity: 1; - --tw-ring-color: rgb(30 66 159 / var(--tw-ring-opacity)); -} - -.dark\:focus\:ring-gray-700:focus:is(.dark *) { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(55 65 81 / var(--tw-ring-opacity)); -} - -@media (min-width: 768px) { - .md\:w-auto { - width: auto; - } - - .md\:flex-nowrap { - flex-wrap: nowrap; - } - - .md\:justify-start { - justify-content: flex-start; - } + --tw-ring-color: rgb(164 202 254 / var(--tw-ring-opacity)); } @media (min-width: 1024px) { - .lg\:w-auto { - width: auto; - } - .lg\:flex-nowrap { flex-wrap: nowrap; } @@ -1970,16 +1947,6 @@ input:checked + .toggle-bg { } } -@media (min-width: 1280px) { - .xl\:w-auto { - width: auto; - } - - .xl\:flex-nowrap { - flex-wrap: nowrap; - } -} - .rtl\:rotate-180:where([dir="rtl"], [dir="rtl"] *) { --tw-rotate: 180deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -1988,3 +1955,131 @@ input:checked + .toggle-bg { .rtl\:space-x-reverse:where([dir="rtl"], [dir="rtl"] *) > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 1; } + +.peer:checked ~ .rtl\:peer-checked\:after\:-translate-x-full:where([dir="rtl"], [dir="rtl"] *)::after { + content: var(--tw-content); + --tw-translate-x: -100%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.dark\:border-blue-500:where(.dark, .dark *) { + --tw-border-opacity: 1; + border-color: rgb(63 131 248 / var(--tw-border-opacity)); +} + +.dark\:border-gray-600:where(.dark, .dark *) { + --tw-border-opacity: 1; + border-color: rgb(75 85 99 / var(--tw-border-opacity)); +} + +.dark\:border-gray-700:where(.dark, .dark *) { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.dark\:border-transparent:where(.dark, .dark *) { + border-color: transparent; +} + +.dark\:bg-blue-600:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(28 100 242 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-600:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-700:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-800:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +.dark\:bg-gray-800\/50:where(.dark, .dark *) { + background-color: rgb(31 41 55 / 0.5); +} + +.dark\:bg-gray-900\/80:where(.dark, .dark *) { + background-color: rgb(17 24 39 / 0.8); +} + +.dark\:bg-slate-800:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(30 41 59 / var(--tw-bg-opacity)); +} + +.dark\:text-blue-500:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(63 131 248 / var(--tw-text-opacity)); +} + +.dark\:text-gray-400:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.dark\:text-white:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.dark\:text-gray-300:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.dark\:hover\:bg-blue-700:hover:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(26 86 219 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-600:hover:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(75 85 99 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-700:hover:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.dark\:hover\:bg-gray-800:hover:where(.dark, .dark *) { + --tw-bg-opacity: 1; + background-color: rgb(31 41 55 / var(--tw-bg-opacity)); +} + +.dark\:hover\:text-blue-500:hover:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(63 131 248 / var(--tw-text-opacity)); +} + +.dark\:hover\:text-gray-300:hover:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(209 213 219 / var(--tw-text-opacity)); +} + +.dark\:hover\:text-white:hover:where(.dark, .dark *) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.dark\:focus\:ring-blue-800:focus:where(.dark, .dark *) { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(30 66 159 / var(--tw-ring-opacity)); +} + +.dark\:focus\:ring-gray-700:focus:where(.dark, .dark *) { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(55 65 81 / var(--tw-ring-opacity)); +} + +.peer:focus ~ .dark\:peer-focus\:ring-blue-800:where(.dark, .dark *) { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(30 66 159 / var(--tw-ring-opacity)); +} diff --git a/tailwind.config.js b/tailwind.config.js index 3b0ae21..8390d14 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { + darkMode: "selector", content: [ "./index.html", "./src/**/*.{html,js}",