Implement dark mode switch (#7)

This commit is contained in:
Ondřej 2022-10-24 03:43:56 +02:00
parent 952a8b94d8
commit d4ccc435c6
12 changed files with 193 additions and 155 deletions

View file

@ -2,47 +2,6 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html {
font-family: theme("fontFamily.main");
font-size: theme("fontSize.2xl");
}
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Color scheme */
.color-scheme--sync .color-scheme--light-icon {
display: none;
}
.color-scheme--sync .color-scheme--dark-icon {
display: block;
}
@media (prefers-color-scheme: dark) {
.color-scheme--sync .color-scheme--light-icon {
display: block;
}
.color-scheme--sync .color-scheme--dark-icon {
display: none;
}
}
.color-scheme--dark .color-scheme--dark-icon,
.color-scheme--light .color-scheme--light-icon {
display: none;
}
.color-scheme--dark .color-scheme--light-icon,
.color-scheme--light .color-scheme--dark-icon {
display: block;
}
/* Typography */ /* Typography */
.prose :is(p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre) { .prose :is(p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre) {
@ -55,25 +14,10 @@ body {
.link, .link,
.prose a { .prose a {
@apply text-red-900 border-b-4 border-red-500/25; @apply text-red-900 hover:text-red-600 dark:text-red-200 dark:hover:text-red-400 border-b-4 border-red-500/25 dark:border-red-200/25;
transition: color 200ms; transition: color 200ms;
} }
.link:hover,
.prose a:hover {
@apply text-red-600;
}
.dark .link,
.dark .prose a {
@apply text-red-200 border-red-200/25;
}
.dark .link:hover,
.dark .prose a:hover {
color: theme("colors.red.400");
}
:is(.list, .prose ul) li { :is(.list, .prose ul) li {
position: relative; position: relative;
margin-left: 1.5em; margin-left: 1.5em;
@ -89,8 +33,7 @@ body {
.subheading, .subheading,
.prose h3 { .prose h3 {
@apply text-sm font-bold; @apply text-sm font-bold text-red-800 dark:text-red-300;
color: theme("colors.red.800");
} }
:is(.subheading, .prose h3)::before { :is(.subheading, .prose h3)::before {
@ -107,7 +50,7 @@ body {
.code-block, .code-block,
pre { pre {
@apply bg-gray-100; @apply bg-gray-100 dark:bg-gray-800;
border-radius: 0.25em; border-radius: 0.25em;
overflow-x: auto; overflow-x: auto;
padding: 1em; padding: 1em;
@ -116,7 +59,7 @@ pre {
.code-inline, .code-inline,
code { code {
@apply bg-gray-100; @apply bg-gray-100 dark:bg-gray-800;
padding: 0.125em 0.25em; padding: 0.125em 0.25em;
border-radius: 0.25em; border-radius: 0.25em;
font-size: 0.875em; font-size: 0.875em;
@ -148,6 +91,16 @@ code {
border-radius: 100px; border-radius: 100px;
} }
.button:hover { .button--opaque {
background-color: theme("colors.gray.200"); @apply bg-white dark:bg-gray-900;
}
.button:hover {
background-color: theme(colors.gray.400 / 25%);
}
/* Utils */
html:not(.dark) .light\:hidden {
display: none;
} }

View file

@ -1,15 +1,13 @@
import Alpine from "alpinejs"; import Alpine from "alpinejs";
import persist from "@alpinejs/persist";
window.Alpine = Alpine; window.Alpine = Alpine;
Alpine.plugin(persist);
Alpine.start(); Alpine.start();
/* Copy button component */ /* Copy button component */
const copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M7 4V2h10v2h3.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H7zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z"/></svg>`; const copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M7 4V2h10v2h3.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H7zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z"/></svg>`;
const checkIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`; const checkIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`;
const defaultButtonLabel = `Zkopírovat text do schránky`; const defaultButtonLabel = `Zkopírovat text do schránky`;
const copiedButtonLabel = `Text zkopírován`; const copiedButtonLabel = `Text zkopírován`;
const revertTimeout = 5_000; const revertTimeout = 5_000;
@ -32,7 +30,7 @@ navigator.permissions
.forEach((codeBlock) => { .forEach((codeBlock) => {
const button = document.createElement("button"); const button = document.createElement("button");
button.innerHTML = defaultButtonContent; button.innerHTML = defaultButtonContent;
button.className = "button absolute top-3 right-3 bg-white"; button.className = "button button--opaque absolute top-3 right-3";
button.addEventListener("click", () => { button.addEventListener("click", () => {
navigator.clipboard.writeText(codeBlock.innerHTML).then(() => { navigator.clipboard.writeText(codeBlock.innerHTML).then(() => {

View file

@ -16,7 +16,7 @@
/* 2 */ /* 2 */
border-style: solid; border-style: solid;
/* 2 */ /* 2 */
border-color: #e5e7eb; border-color: #e4e4e7;
/* 2 */ /* 2 */
} }
@ -351,7 +351,7 @@ textarea {
input::-moz-placeholder, textarea::-moz-placeholder { input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1; opacity: 1;
/* 1 */ /* 1 */
color: #9ca3af; color: #a1a1aa;
/* 2 */ /* 2 */
} }
@ -359,7 +359,7 @@ input::placeholder,
textarea::placeholder { textarea::placeholder {
opacity: 1; opacity: 1;
/* 1 */ /* 1 */
color: #9ca3af; color: #a1a1aa;
/* 2 */ /* 2 */
} }
@ -704,6 +704,10 @@ video {
display: none; display: none;
} }
.min-h-screen {
min-height: 100vh;
}
.max-w-screen-md { .max-w-screen-md {
max-width: 768px; max-width: 768px;
} }
@ -782,14 +786,29 @@ video {
background-color: rgb(185 28 28 / var(--tw-bg-opacity)); background-color: rgb(185 28 28 / var(--tw-bg-opacity));
} }
.bg-gray-100 { .bg-gray-50 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity)); background-color: rgb(250 250 250 / var(--tw-bg-opacity));
} }
.bg-white { .bg-gray-100 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: rgb(244 244 245 / var(--tw-bg-opacity));
}
.bg-red-800 {
--tw-bg-opacity: 1;
background-color: rgb(153 27 27 / var(--tw-bg-opacity));
}
.bg-red-900 {
--tw-bg-opacity: 1;
background-color: rgb(127 29 29 / var(--tw-bg-opacity));
}
.bg-gray-800 {
--tw-bg-opacity: 1;
background-color: rgb(39 39 42 / var(--tw-bg-opacity));
} }
.px-6 { .px-6 {
@ -812,6 +831,10 @@ video {
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
} }
.pt-6 {
padding-top: 1.5rem;
}
.pt-4 { .pt-4 {
padding-top: 1rem; padding-top: 1rem;
} }
@ -824,6 +847,15 @@ video {
padding-bottom: 3rem; padding-bottom: 3rem;
} }
.font-main {
font-family: Spline Sans, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-sm { .text-sm {
font-size: 0.875rem; font-size: 0.875rem;
line-height: 1.25rem; line-height: 1.25rem;
@ -847,14 +879,22 @@ video {
font-weight: 500; font-weight: 500;
} }
.leading-normal {
line-height: 1.5;
}
.text-white { .text-white {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity)); color: rgb(255 255 255 / var(--tw-text-opacity));
} }
.text-gray-500 { .text-gray-900 {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity)); color: rgb(24 24 27 / var(--tw-text-opacity));
}
.text-gray-900\/50 {
color: rgb(24 24 27 / 0.5);
} }
.transition-transform { .transition-transform {
@ -863,47 +903,6 @@ video {
transition-duration: 150ms; transition-duration: 150ms;
} }
html {
font-family: Spline Sans, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1.5rem;
}
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Color scheme */
.color-scheme--sync .color-scheme--light-icon {
display: none;
}
.color-scheme--sync .color-scheme--dark-icon {
display: block;
}
@media (prefers-color-scheme: dark) {
.color-scheme--sync .color-scheme--light-icon {
display: block;
}
.color-scheme--sync .color-scheme--dark-icon {
display: none;
}
}
.color-scheme--dark .color-scheme--dark-icon,
.color-scheme--light .color-scheme--light-icon {
display: none;
}
.color-scheme--dark .color-scheme--light-icon,
.color-scheme--light .color-scheme--dark-icon {
display: block;
}
/* Typography */ /* Typography */
.prose :is(p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre) { .prose :is(p, h1, h2, h3, h4, h5, h6, ul, ol, li, pre) {
@ -920,7 +919,6 @@ body {
border-color: rgb(239 68 68 / 0.25); border-color: rgb(239 68 68 / 0.25);
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(127 29 29 / var(--tw-text-opacity)); color: rgb(127 29 29 / var(--tw-text-opacity));
transition: color 200ms;
} }
.link:hover, .link:hover,
@ -929,16 +927,22 @@ body {
color: rgb(220 38 38 / var(--tw-text-opacity)); color: rgb(220 38 38 / var(--tw-text-opacity));
} }
.dark .link, .dark .link,.dark
.dark .prose a { .prose a {
border-color: rgb(254 202 202 / 0.25); border-color: rgb(254 202 202 / 0.25);
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(254 202 202 / var(--tw-text-opacity)); color: rgb(254 202 202 / var(--tw-text-opacity));
} }
.dark .link:hover, .dark .link:hover,.dark
.dark .prose a:hover { .prose a:hover {
color: #f87171; --tw-text-opacity: 1;
color: rgb(248 113 113 / var(--tw-text-opacity));
}
.link,
.prose a {
transition: color 200ms;
} }
:is(.list, .prose ul) li { :is(.list, .prose ul) li {
@ -959,7 +963,14 @@ body {
font-size: 0.875rem; font-size: 0.875rem;
line-height: 1.25rem; line-height: 1.25rem;
font-weight: 700; font-weight: 700;
color: #991b1b; --tw-text-opacity: 1;
color: rgb(153 27 27 / var(--tw-text-opacity));
}
.dark .subheading,.dark
.prose h3 {
--tw-text-opacity: 1;
color: rgb(252 165 165 / var(--tw-text-opacity));
} }
:is(.subheading, .prose h3)::before { :is(.subheading, .prose h3)::before {
@ -978,7 +989,17 @@ body {
.code-block, .code-block,
pre { pre {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity)); background-color: rgb(244 244 245 / var(--tw-bg-opacity));
}
.dark .code-block,.dark
pre {
--tw-bg-opacity: 1;
background-color: rgb(39 39 42 / var(--tw-bg-opacity));
}
.code-block,
pre {
border-radius: 0.25em; border-radius: 0.25em;
overflow-x: auto; overflow-x: auto;
padding: 1em; padding: 1em;
@ -988,7 +1009,17 @@ pre {
.code-inline, .code-inline,
code { code {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity)); background-color: rgb(244 244 245 / var(--tw-bg-opacity));
}
.dark .code-inline,.dark
code {
--tw-bg-opacity: 1;
background-color: rgb(39 39 42 / var(--tw-bg-opacity));
}
.code-inline,
code {
padding: 0.125em 0.25em; padding: 0.125em 0.25em;
border-radius: 0.25em; border-radius: 0.25em;
font-size: 0.875em; font-size: 0.875em;
@ -1008,7 +1039,7 @@ code {
} }
} }
@media (min-width: 1280px) { @media (min-width: 1024px) {
.clip-wedge { .clip-wedge {
--wedge-skew: 5vw; --wedge-skew: 5vw;
} }
@ -1021,8 +1052,52 @@ code {
border-radius: 100px; border-radius: 100px;
} }
.button--opaque {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.dark .button--opaque {
--tw-bg-opacity: 1;
background-color: rgb(24 24 27 / var(--tw-bg-opacity));
}
.button:hover { .button:hover {
background-color: #e5e7eb; background-color: rgb(161 161 170 / 25%);
}
/* Utils */
html:not(.dark) .light\:hidden {
display: none;
}
.dark .dark\:hidden {
display: none;
}
.dark .dark\:border-gray-800 {
--tw-border-opacity: 1;
border-color: rgb(39 39 42 / var(--tw-border-opacity));
}
.dark .dark\:bg-gray-900 {
--tw-bg-opacity: 1;
background-color: rgb(24 24 27 / var(--tw-bg-opacity));
}
.dark .dark\:bg-gray-800 {
--tw-bg-opacity: 1;
background-color: rgb(39 39 42 / var(--tw-bg-opacity));
}
.dark .dark\:text-gray-50 {
--tw-text-opacity: 1;
color: rgb(250 250 250 / var(--tw-text-opacity));
}
.dark .dark\:text-gray-50\/50 {
color: rgb(250 250 250 / 0.5);
} }
@media not all and (min-width: 1024px) { @media not all and (min-width: 1024px) {
@ -1109,4 +1184,8 @@ code {
.lg\:pb-2 { .lg\:pb-2 {
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
} }
.dark .dark\:lg\:bg-transparent {
background-color: transparent;
}
} }

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="nojs" lang="{{ site.LanguageCode | default site.Language.Lang }}" dir="{{ site.Language.LanguageDirection | default "ltr" }}"> <html class="font-main leading-normal text-2xl" lang="{{ site.LanguageCode | default site.Language.Lang }}" dir="{{ site.Language.LanguageDirection | default "ltr" }}">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
@ -13,9 +13,9 @@
</head> </head>
<body <body
class="overflow-x-hidden" class="overflow-x-hidden min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-50"
x-data="{ colorScheme: $persist('sync'), menuOpen: false }" x-data="{ menuOpen: false }"
x-bind:class="`color-scheme--${colorScheme} ${menuOpen ? 'overflow-hidden' : ''}`" x-bind:class="`${menuOpen ? 'overflow-hidden' : ''}`"
> >
<header class="py-4"> <header class="py-4">
<div class="container mx-auto px-6 flex items-center lg:mb-4 gap-6"> <div class="container mx-auto px-6 flex items-center lg:mb-4 gap-6">
@ -28,7 +28,7 @@
<button class="button lg:hidden" x-on:click="menuOpen = true"> <button class="button lg:hidden" x-on:click="menuOpen = true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32">
<path fill="none" d="M0 0h24v24H0z"/> <path fill="none" d="M0 0h24v24H0z"/>
<path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/> <path fill="currentColor" d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/>
</svg> </svg>
</button> </button>
</div> </div>
@ -38,7 +38,7 @@
{{ block "main" . }}{{ end }} {{ block "main" . }}{{ end }}
<footer class="mt-6 text-gray-500 mt-auto"> <footer class="pt-6 text-gray-900/50 dark:text-gray-50/50 mt-auto">
<div class="container mx-auto px-6 py-6"> <div class="container mx-auto px-6 py-6">
{{ if $.Param "feedlinks" }} {{ if $.Param "feedlinks" }}
{{ partial "feedlinks.html" . }} {{ partial "feedlinks.html" . }}

View file

@ -1,5 +1,5 @@
{{ define "main" -}} {{ define "main" -}}
<main class="border-t pt-4"> <main class="border-t dark:border-gray-800 pt-4">
<header class="container mx-auto px-6 mb-6"> <header class="container mx-auto px-6 mb-6">
<h1 class="font-bold">{{ .Title }}</h1> <h1 class="font-bold">{{ .Title }}</h1>
</header> </header>

View file

@ -1,6 +1,6 @@
{{ define "main" -}} {{ define "main" -}}
<main> <main>
<article class="border-t pt-4"> <article class="border-t dark:border-gray-800 pt-4">
<header class="container mx-auto px-6 mb-6"> <header class="container mx-auto px-6 mb-6">
<h1 class="font-bold {{ if $.Param "submitted" | default false }}title-submitted{{ end }}">{{ .Title }}</h1> <h1 class="font-bold {{ if $.Param "submitted" | default false }}title-submitted{{ end }}">{{ .Title }}</h1>
{{ if $.Param "submitted" | default false }}{{ partial "submitted.html" . }}{{ end -}} {{ if $.Param "submitted" | default false }}{{ partial "submitted.html" . }}{{ end -}}

View file

@ -11,7 +11,7 @@
</div> </div>
</section> </section>
<section class="py-24 clip-wedge bg-red-700 text-white dark"> <section class="py-24 clip-wedge bg-red-800 text-white dark">
<div class="container mx-auto px-6"> <div class="container mx-auto px-6">
{{ partial "services.html" }} {{ partial "services.html" }}
</div> </div>

View file

@ -1,9 +1,9 @@
<nav <nav
class="bg-gray-100 lg:bg-transparent fixed lg:static inset-0 z-10 overflow-y-auto transition-transform lg:container lg:mx-auto px-6 pt-12 pb-12 lg:pt-0 lg:pb-2" class="bg-gray-100 dark:bg-gray-800 lg:bg-transparent dark:lg:bg-transparent fixed lg:static inset-0 z-10 overflow-y-auto transition-transform lg:container lg:mx-auto px-6 pt-12 pb-12 lg:pt-0 lg:pb-2"
x-bind:class="menuOpen ? 'translate-x-0' : 'translate-x-full lg:translate-x-0'"> x-bind:class="menuOpen ? 'translate-x-0' : 'translate-x-full lg:translate-x-0'">
<h2 class="sr-only">{{ i18n "menu_title" }}</h2> <h2 class="sr-only">{{ i18n "menu_title" }}</h2>
<button class="button block mb-6 lg:hidden absolute top-4 right-6" x-on:click="menuOpen = false"> <button class="button block mb-6 lg:hidden absolute top-4 right-6" x-on:click="menuOpen = false">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32"><path fill="none" d="M0 0h24v24H0z"/><path fill="currentColor" d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
</button> </button>
<ul class="flex gap-x-6 gap-y-4 flex-col lg:flex-row"> <ul class="flex gap-x-6 gap-y-4 flex-col lg:flex-row">
{{ range site.Menus.main }} {{ range site.Menus.main }}

View file

@ -1,2 +1,12 @@
<script>
const themeChoice = localStorage.getItem("theme")
document.documentElement.classList.toggle(
"dark",
themeChoice !== null
? themeChoice === "dark"
: window.matchMedia("(prefers-color-scheme: dark)").matches
);
</script>
{{- $js := resources.Get "main.js" | js.Build | fingerprint -}} {{- $js := resources.Get "main.js" | js.Build | fingerprint -}}
<script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}" defer ></script> <script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}" defer ></script>

View file

@ -1,6 +1,6 @@
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Spline+Sans:ital,wght@0,400;0,500;0,700;1,400;1,700&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Spline+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet" />
{{ $style := resources.Get "style.css" }} {{ $style := resources.Get "style.css" }}

View file

@ -1,27 +1,22 @@
<h2 class="sr-only">{{ i18n "theme_select_title" }}</h2> <h2 class="sr-only">{{ i18n "theme_select_title" }}</h2>
<button x-on:click="toggleColorScheme" class="button"> <button x-on:click="toggleColorScheme" class="button">
<svg class="color-scheme--icon color-scheme--light-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32"> <svg class="dark:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32">
<g> <g>
<path fill="none" d="M0 0h24v24H0z"/> <path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/> <path fill="currentColor" fill-rule="nonzero" d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/>
</g> </g>
</svg> </svg>
<svg class="color-scheme--icon color-scheme--dark-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32"> <svg class="light:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32">
<g> <g>
<path fill="none" d="M0 0h24v24H0z"/> <path fill="none" d="M0 0h24v24H0z"/>
<path fill-rule="nonzero" d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/> <path fill="currentColor" fill-rule="nonzero" d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/>
</g> </g>
</svg> </svg>
</button> </button>
<script> <script>
function toggleColorScheme() { function toggleColorScheme() {
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches document.documentElement.classList.toggle("dark")
localStorage.setItem("theme", document.documentElement.classList.contains("dark") ? "dark" : "light")
if (this.colorScheme === 'sync') {
this.colorScheme = prefersDarkMode ? 'light' : 'dark'
} else {
this.colorScheme = this.colorScheme === 'dark' ? 'light' : 'dark'
}
} }
</script> </script>

View file

@ -1,8 +1,9 @@
const colors = require("tailwindcss/"); const colors = require("tailwindcss/colors");
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["content/**/*.md", "layouts/**/*.html", "assets/**/*.js"], content: ["content/**/*.md", "layouts/**/*.html", "assets/**/*.js"],
darkMode: "class",
theme: { theme: {
fontFamily: { fontFamily: {
main: [ main: [
@ -28,7 +29,9 @@ module.exports = {
semibold: 500, semibold: 500,
}, },
extend: { extend: {
// colors: {
gray: colors.zinc,
},
}, },
}, },
plugins: [], plugins: [],