dark light mode
This commit is contained in:
@@ -11,6 +11,13 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}Komp Accounting{% endblock %} · Komp Accounting</title>
|
||||
<script>
|
||||
// Runs before any stylesheet so the `dark` class is already on <html> at
|
||||
// first paint — otherwise the page would flash light before this fires.
|
||||
// Dark is the default: only an explicit "light" choice in localStorage
|
||||
// (set by the toggle in ui/navbar.html) turns it off.
|
||||
document.documentElement.classList.toggle('dark', localStorage.getItem('theme') !== 'light');
|
||||
</script>
|
||||
{#
|
||||
Cascade order, declared before anything ships CSS so that it is this line
|
||||
that decides it. `app` is static/app.css, which is wrapped in that layer:
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<li><a href="/login" class="{% if nav.active == "login" %}font-bold text-primary dark:text-primary-dark{% else %}font-medium text-on-surface dark:text-on-surface-dark dark:hover:text-primary-dark{% endif %} underline-offset-2 hover:text-primary focus:outline-hidden focus:underline" {% if nav.active == "login" %}aria-current="page"{% endif %}>{{ nav.tr("nav-login") }}</a></li>
|
||||
<li><a href="/register" class="{% if nav.active == "register" %}font-bold text-primary dark:text-primary-dark{% else %}font-medium text-on-surface dark:text-on-surface-dark dark:hover:text-primary-dark{% endif %} underline-offset-2 hover:text-primary focus:outline-hidden focus:underline" {% if nav.active == "register" %}aria-current="page"{% endif %}>{{ nav.tr("nav-register") }}</a></li>
|
||||
{% endif %}
|
||||
<li>{% include "ui/theme_toggle.html" %}</li>
|
||||
</ul>
|
||||
<!-- Mobile Menu Button -->
|
||||
<button x-on:click="mobileMenuIsOpen = !mobileMenuIsOpen" x-bind:aria-expanded="mobileMenuIsOpen" x-bind:class="mobileMenuIsOpen ? 'fixed top-6 right-6 z-20' : null" type="button" class="flex text-on-surface dark:text-on-surface-dark md:hidden" aria-label="{{ nav.tr("nav-mobile-menu") }}" aria-controls="mobileMenu">
|
||||
@@ -60,5 +61,6 @@
|
||||
<li class="py-4"><a href="/login" class="w-full text-lg {% if nav.active == "login" %}font-bold text-primary dark:text-primary-dark{% else %}font-medium text-on-surface dark:text-on-surface-dark{% endif %} focus:underline" {% if nav.active == "login" %}aria-current="page"{% endif %}>{{ nav.tr("nav-login") }}</a></li>
|
||||
<li class="py-4"><a href="/register" class="w-full text-lg {% if nav.active == "register" %}font-bold text-primary dark:text-primary-dark{% else %}font-medium text-on-surface dark:text-on-surface-dark{% endif %} focus:underline" {% if nav.active == "register" %}aria-current="page"{% endif %}>{{ nav.tr("nav-register") }}</a></li>
|
||||
{% endif %}
|
||||
<li class="py-4">{% include "ui/theme_toggle.html" %}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
20
web/templates/ui/theme_toggle.html
Normal file
20
web/templates/ui/theme_toggle.html
Normal file
@@ -0,0 +1,20 @@
|
||||
{#
|
||||
Dark/light toggle, included twice by ui/navbar.html (desktop menu and
|
||||
mobile menu). Initial state mirrors whatever base.html's inline script
|
||||
already put on <html>, so this never fights that on first render; clicking
|
||||
it flips both the class and the localStorage flag that script reads.
|
||||
#}
|
||||
<button
|
||||
type="button"
|
||||
x-data="{ dark: document.documentElement.classList.contains('dark') }"
|
||||
x-on:click="dark = !dark; document.documentElement.classList.toggle('dark', dark); localStorage.setItem('theme', dark ? 'dark' : 'light')"
|
||||
class="flex text-on-surface hover:text-primary focus:outline-hidden dark:text-on-surface-dark dark:hover:text-primary-dark"
|
||||
aria-label="{{ nav.tr("nav-toggle-theme") }}"
|
||||
>
|
||||
<svg x-cloak x-show="!dark" xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
|
||||
</svg>
|
||||
<svg x-cloak x-show="dark" xmlns="http://www.w3.org/2000/svg" fill="none" aria-hidden="true" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
|
||||
</svg>
|
||||
</button>
|
||||
Reference in New Issue
Block a user