feat: add light/dark mode toggle with header view transitions

Add theme cycling (system/light/dark) with localStorage persistence
and FOUC prevention. Restructure CSS color tokens to respond to
data-theme attribute across all components. Redesign header as a
floating glass pill bar with smooth view transitions including
clip-reveal logo animation.
This commit is contained in:
2026-03-01 16:15:36 +01:00
parent 3942a18b2b
commit fdbbca3942
82 changed files with 2317 additions and 1276 deletions
+13 -3
View File
@@ -23,10 +23,14 @@ let { onclick } = $props<{ onclick?: () => void }>();
}
@media(prefers-color-scheme: light) {
.counter-button {
:global(:root:not([data-theme="dark"])) .counter-button {
background: var(--nord5);
border-color: var(--nord10);
}
}
:global(:root[data-theme="light"]) .counter-button {
background: var(--nord5);
border-color: var(--nord10);
}
.counter-button:hover {
@@ -35,9 +39,12 @@ let { onclick } = $props<{ onclick?: () => void }>();
}
@media(prefers-color-scheme: light) {
.counter-button:hover {
:global(:root:not([data-theme="dark"])) .counter-button:hover {
background: var(--nord4);
}
}
:global(:root[data-theme="light"]) .counter-button:hover {
background: var(--nord4);
}
.counter-button svg {
@@ -48,9 +55,12 @@ let { onclick } = $props<{ onclick?: () => void }>();
}
@media(prefers-color-scheme: light) {
.counter-button svg {
:global(:root:not([data-theme="dark"])) .counter-button svg {
fill: var(--nord10);
}
}
:global(:root[data-theme="light"]) .counter-button svg {
fill: var(--nord10);
}
.counter-button:hover svg {
+9 -2
View File
@@ -28,13 +28,20 @@
}
@media (prefers-color-scheme: dark) {
.form-section {
:global(:root:not([data-theme="light"])) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
.form-section h2 {
:global(:root:not([data-theme="light"])) .form-section h2 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .form-section h2 {
color: var(--font-default-dark);
}
</style>
+248 -321
View File
@@ -1,7 +1,6 @@
<script lang="ts">
import { onMount } from "svelte";
import { page } from '$app/stores';
import Symbol from "./Symbol.svelte"
import ThemeToggle from "./ThemeToggle.svelte"
import type { Snippet } from 'svelte';
let {
@@ -9,326 +8,211 @@ let {
language_selector_mobile,
language_selector_desktop,
right_side,
children
children,
fullSymbol = false
}: {
links?: Snippet;
language_selector_mobile?: Snippet;
language_selector_desktop?: Snippet;
right_side?: Snippet;
children?: Snippet;
fullSymbol?: boolean;
} = $props();
let underlineLeft = $state(0);
let underlineWidth = $state(0);
let disableTransition = $state(false);
function toggle_sidebar(state){
const checkbox = document.getElementById('nav-toggle')
if(state === undefined) checkbox.checked = !checkbox.checked
else checkbox.checked = !state
}
function updateUnderline() {
const activeLink = document.querySelector('.site_header a.active');
const linksWrapper = document.querySelector('.links-wrapper');
if (activeLink && linksWrapper) {
const wrapperRect = linksWrapper.getBoundingClientRect();
const linkRect = activeLink.getBoundingClientRect();
// Get computed padding to exclude from width and adjust position
const computedStyle = window.getComputedStyle(activeLink);
const paddingLeft = parseFloat(computedStyle.paddingLeft);
const paddingRight = parseFloat(computedStyle.paddingRight);
underlineLeft = linkRect.left - wrapperRect.left + paddingLeft;
underlineWidth = linkRect.width - paddingLeft - paddingRight;
} else {
underlineWidth = 0;
}
}
// Update underline when page changes
$effect(() => {
$page.url.pathname; // Subscribe to pathname changes
// Use setTimeout to ensure DOM has updated
setTimeout(updateUnderline, 0);
});
onMount( () => {
const link_els = document.querySelectorAll("nav a")
link_els.forEach((el) => {
el.addEventListener("click", () => {toggle_sidebar(true)});
})
// Initialize underline position
updateUnderline();
// Update underline on resize, with transition disabled
let resizeTimer;
function handleResize() {
disableTransition = true;
updateUnderline(); // Update immediately to prevent lag
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
// Re-enable transition after resize has settled
disableTransition = false;
}, 150);
}
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
clearTimeout(resizeTimer);
};
})
</script>
<style>
nav{
position: sticky;
background-color: var(--nord0);
top: 0;
z-index: 10;
display: flex;
flex-direction: row;
justify-content: space-between !important;
align-items: center;
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
height: var(--header-h);
padding-left: 0.5rem;
view-transition-name: site-header;
}
.nav-toggle{
display: none;
}
:global(.site_header li),
:global(a.entry)
{
list-style-type:none;
transition: color 100ms;
color: white;
user-select: none;
}
:global(.site_header li>a)
{
text-decoration: none;
font-size: 1rem;
color: inherit;
border-radius: var(--radius-pill);
padding: 0.4rem 0.6rem;
}
:global(a.entry),
:global(a.entry:link),
:global(a.entry:visited)
{
text-decoration: none;
font-size: 1rem;
color: white !important;
border-radius: var(--radius-pill);
padding: 0.4rem 0.6rem;
}
:global(.site_header li:hover),
:global(.site_header li:focus-within),
:global(.site_header li:has(a.active)),
:global(a.entry:hover),
:global(a.entry:focus-visible),
:global(a.entry:link:hover),
:global(a.entry:visited:hover),
:global(a.entry:visited:focus-visible)
{
cursor: pointer;
color: var(--nord8) !important;
}
:global(.site_header) {
padding-block: 1.5rem;
display: flex;
flex-direction: row;
gap: 0.5rem;
justify-content: space-evenly;
max-width: 1000px;
margin: 0;
margin-inline: auto;
}
.links-wrapper {
position: relative;
flex: 1;
}
.active-underline {
position: absolute;
bottom: 1.4rem;
height: 1.25px;
background-color: var(--nord8);
transition: left 300ms ease-out, width 300ms ease-out;
pointer-events: none;
}
.active-underline.no-transition {
transition: none;
}
.nav_button{
display: none;
}
.button_wrapper{
display: none;
padding-inline: 0.5rem;
}
.header-shadow{
display: none;
}
.right-buttons{
display: flex;
align-items: center;
gap: 0.5rem;
}
.header-right{
display: flex;
align-items: center;
gap: 0.5rem;
}
:global(svg.symbol){
--symbol-size: calc(var(--header-h) - 1rem);
width: var(--symbol-size);
border-radius: 10000px;
margin: 0.25rem;
}
/*:global(a:has(svg.symbol)){
padding: 0 !important;
width: 4rem;
height: 4rem;
margin-left: 1rem;
}*/
.wrapper{
/* ═══════════════════════════════════════════
WRAPPER & LAYOUT
═══════════════════════════════════════════ */
.wrapper {
--header-h: 3rem;
--symbol-size: calc(var(--header-h) - 1rem);
display:flex;
display: flex;
flex-direction: column;
min-height: 100svh;
}
footer{
footer {
padding-block: 1rem;
text-align: center;
margin-top: auto;
position: relative;
}
@media screen and (max-width: 800px) {
.button_wrapper{
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
background-color: var(--nord0);
width: 100%;
height: var(--header-h);
top: 0;
z-index: 9999;
}
.header-shadow{
display: block;
position: sticky;
top: 0;
width: 100%;
height: var(--header-h);
margin-top: calc(-1 * var(--header-h));
box-shadow: 0 1em 1rem 0rem rgba(0,0,0,0.4);
z-index: 9997;
pointer-events: none;
}
.nav_button{
display: inline-flex;
align-items: center;
justify-content: center;
fill: white;
margin-inline: 0.5rem;
width: 1.25rem;
height: 1.25rem;
cursor: pointer;
}
.nav_button svg{
width: 100%;
height: 100%;
transition: var(--transition-fast);
}
.nav_button:hover,
.nav_button:active,
.nav-toggle:focus-visible + .nav_button{
fill: var(--nord8);
scale: 0.9;
}
.nav_site:not(.no-links){
position: fixed;
top: 0;
right: 0;
height: 100vh; /* dvh does not work, breaks because of transition and only being applied after scroll ends*/
margin-bottom: 50vh;
width: min(95svw, 25em);
z-index: 9998;
flex-direction: column;
padding-inline: 0.5rem;
}
.nav_site:not(.no-links)::before{
content: '';
flex: 1;
}
:global(.nav_site:not(.no-links) ul){
width: 100% ;
}
.nav_site:not(.no-links) :first-child{
display:none;
}
.nav_site:not(.no-links){
transform: translateX(100%);
}
.wrapper:has(.nav-toggle:checked) .nav_site:not(.no-links){
transform: translateX(0);
transition: transform 100ms;
}
:global(.nav_site:not(.no-links) a:last-child){
margin-bottom: 2rem;
}
/* ═══════════════════════════════════════════
FLOATING GLASS BAR
═══════════════════════════════════════════ */
nav {
position: sticky;
top: 12px;
z-index: 100;
display: flex;
align-items: center;
height: var(--header-h);
gap: 0.4rem;
padding: 0 0.8rem;
margin: 12px auto 0;
width: fit-content;
max-width: calc(100% - 1.5rem);
border-radius: 100px;
background: var(--nav-bg, rgba(46, 52, 64, 0.82));
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--nav-border, rgba(255,255,255,0.08));
box-shadow: 0 4px 24px var(--nav-shadow, rgba(0,0,0,0.25));
view-transition-name: site-header;
.nav_site:not(.no-links) .links-wrapper {
width: 100%;
padding: 0 2rem;
/* token defaults (dark bar) */
--nav-text: rgba(255,255,255,0.65);
--nav-text-hover: white;
--nav-text-active: white;
--nav-hover-bg: rgba(255,255,255,0.1);
--nav-active-bg: rgba(136, 192, 208, 0.25);
--nav-btn-border: rgba(255,255,255,0.2);
--nav-btn-border-hover: rgba(255,255,255,0.4);
--nav-divider: rgba(255,255,255,0.15);
}
/* Dark system preference */
@media (prefers-color-scheme: dark) {
nav {
--nav-bg: rgba(20, 20, 20, 0.78);
--nav-border: rgba(255,255,255,0.06);
}
:global(.site_header){
flex-direction: column;
align-items: flex-start;
}
:global(.site_header li, .site_header a){
font-size: 1.5rem;
}
:global(.site_header li > a, .site_header a){
font-size: 1.3rem;
}
:global(.site_header li:hover),
:global(.site_header li:focus-within){
transform: unset;
}
.nav_site:not(.no-links) .header-right{
flex-direction: column;
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
}
.nav_site:not(.no-links) .language-selector-desktop{
display: none;
}
.active-underline {
display: none;
}
:global(.nav_site .site_header a.active) {
text-decoration: underline;
text-decoration-color: var(--nord8);
text-decoration-thickness: 1px;
text-underline-offset: 0.2rem;
}
/* User forced dark */
:global(:root[data-theme="dark"]) nav {
--nav-bg: rgba(20, 20, 20, 0.78);
--nav-border: rgba(255,255,255,0.06);
}
/* User forced light — OR system light (default, already handled by base values) */
:global(:root[data-theme="light"]) nav {
--nav-bg: rgba(255, 255, 255, 0.82);
--nav-border: rgba(0,0,0,0.08);
--nav-shadow: rgba(0,0,0,0.1);
--nav-text: rgba(0,0,0,0.55);
--nav-text-hover: var(--nord0);
--nav-text-active: var(--nord0);
--nav-hover-bg: rgba(0,0,0,0.06);
--nav-active-bg: rgba(94, 129, 172, 0.15);
--nav-btn-border: rgba(0,0,0,0.15);
--nav-btn-border-hover: rgba(0,0,0,0.3);
--nav-divider: rgba(0,0,0,0.12);
}
/* System light preference (no data-theme set) */
@media (prefers-color-scheme: light) {
:global(:root:not([data-theme])) nav {
--nav-bg: rgba(255, 255, 255, 0.82);
--nav-border: rgba(0,0,0,0.08);
--nav-shadow: rgba(0,0,0,0.1);
--nav-text: rgba(0,0,0,0.55);
--nav-text-hover: var(--nord0);
--nav-text-active: var(--nord0);
--nav-hover-bg: rgba(0,0,0,0.06);
--nav-active-bg: rgba(94, 129, 172, 0.15);
--nav-btn-border: rgba(0,0,0,0.15);
--nav-btn-border-hover: rgba(0,0,0,0.3);
--nav-divider: rgba(0,0,0,0.12);
}
}
/* ═══════════════════════════════════════════
LOGO
═══════════════════════════════════════════ */
.home-link {
view-transition-name: nav-logo;
display: flex;
align-items: center;
overflow: hidden;
flex-shrink: 0;
/* icon-only width by default */
width: 20px;
}
.home-link.full {
/* full logo with text */
width: 134px;
}
.home-link :global(svg) {
height: 32px;
width: 134px;
flex-shrink: 0;
}
/* ═══════════════════════════════════════════
NAV LINKS (rendered via snippet)
═══════════════════════════════════════════ */
.links-wrapper {
display: contents;
}
:global(.site_header) {
display: flex;
flex-direction: row;
gap: 0.15rem;
margin: 0;
padding: 0;
list-style: none;
}
:global(.site_header li) {
list-style-type: none;
}
:global(.site_header li > a) {
display: flex;
align-items: center;
gap: 0.35rem;
padding: 0.35rem 0.65rem;
font-size: 0.8rem;
color: var(--nav-text);
text-decoration: none;
border-radius: 100px;
transition: all 150ms;
white-space: nowrap;
}
:global(a.entry),
:global(a.entry:link),
:global(a.entry:visited) {
display: block;
padding: 0.35rem 0.65rem;
font-size: 0.8rem;
color: var(--nav-text) !important;
text-decoration: none;
border-radius: 100px;
transition: all 150ms;
white-space: nowrap;
}
:global(.site_header li:hover > a),
:global(.site_header li:focus-within > a),
:global(a.entry:hover),
:global(a.entry:focus-visible) {
color: var(--nav-text-hover) !important;
background: var(--nav-hover-bg);
cursor: pointer;
}
:global(.site_header li:has(a.active) > a),
:global(.site_header a.active) {
color: var(--nav-text-active) !important;
background: var(--nav-active-bg);
}
/* ═══════════════════════════════════════════
DIVIDER & RIGHT SIDE
═══════════════════════════════════════════ */
.spacer {
width: 1px;
height: 18px;
background: var(--nav-divider);
margin: 0 0.2rem;
flex-shrink: 0;
}
.header-right {
display: flex;
align-items: center;
gap: 0.4rem;
flex-shrink: 0;
view-transition-name: nav-right;
}
/* ═══════════════════════════════════════════
NO-LINKS VARIANT (pages without nav)
═══════════════════════════════════════════ */
.no-links {
gap: 0.5rem;
}
.no-links :global(button) {
margin-bottom: 0 !important;
}
@@ -341,7 +225,7 @@ footer{
}
.no-links :global(.top.speech::after) {
border: 20px solid transparent !important;
border-bottom-color: var(--nord3) !important;
border-bottom-color: var(--color-border) !important;
border-top: 0 !important;
top: -10px !important;
bottom: unset !important;
@@ -352,30 +236,73 @@ footer{
.no-links :global(button::before) {
display: none;
}
/* ═══════════════════════════════════════════
VIEW TRANSITIONS
═══════════════════════════════════════════ */
/* Let the header bar morph its width smoothly */
:global(::view-transition-group(site-header)),
:global(::view-transition-group(nav-logo)),
:global(::view-transition-group(nav-right)) {
animation-duration: 300ms;
animation-timing-function: ease;
overflow: hidden;
}
/* Header & right side: standard morph */
:global(::view-transition-old(site-header)),
:global(::view-transition-new(site-header)),
:global(::view-transition-old(nav-right)),
:global(::view-transition-new(nav-right)) {
animation-duration: 300ms;
animation-timing-function: ease;
height: 100%;
}
/* Logo: clip-reveal instead of scale — keep natural size, left-aligned */
:global(::view-transition-old(nav-logo)),
:global(::view-transition-new(nav-logo)) {
animation: none;
object-fit: none;
object-position: left center;
height: 100%;
}
/* ═══════════════════════════════════════════
MOBILE: compact pill, horizontal scroll
═══════════════════════════════════════════ */
@media screen and (max-width: 800px) {
nav {
gap: 0.25rem;
padding: 0.4rem 0.6rem;
max-width: calc(100% - 1rem);
}
/* Mobile: hide labels, keep icons */
:global(.site_header .nav-label) {
display: none;
}
:global(.site_header li > a) {
padding: 0.4rem;
}
:global(a.entry) {
font-size: 0.75rem;
padding: 0.3rem 0.5rem;
}
}
</style>
<div class=wrapper lang=de>
<div class="wrapper" lang="de">
<div>
{#if links}
<div class=button_wrapper>
<a href="/" aria-label="Home"><Symbol></Symbol></a>
<div class="right-buttons">
{@render language_selector_mobile?.()}
<input type="checkbox" id="nav-toggle" class="nav-toggle" aria-label="Toggle navigation menu" />
<label for="nav-toggle" class=nav_button aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" height="0.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></label>
</div>
</div>
<div class="header-shadow"></div>
{/if}
<nav class=nav_site class:no-links={!links}>
<a href="/" aria-label="Home"><Symbol></Symbol></a>
<div class="links-wrapper">
{@render links?.()}
<div class="active-underline" class:no-transition={disableTransition} style="left: {underlineLeft}px; width: {underlineWidth}px;"></div>
</div>
<div class="header-right">
<div class="language-selector-desktop">
{@render language_selector_desktop?.()}
<nav class:no-links={!links}>
<a href="/" aria-label="Home" class="home-link" class:full={fullSymbol}><Symbol /></a>
{#if links}
<div class="links-wrapper">
{@render links()}
</div>
<div class="spacer"></div>
{/if}
<div class="header-right">
<ThemeToggle />
{@render language_selector_desktop?.()}
{@render right_side?.()}
</div>
</nav>
+34 -8
View File
@@ -126,15 +126,22 @@
}
@media (prefers-color-scheme: dark) {
.form-section {
:global(:root:not([data-theme="light"])) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
.form-section h2 {
:global(:root:not([data-theme="light"])) .form-section h2 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .form-section h2 {
color: var(--font-default-dark);
}
.image-upload {
border: 2px dashed var(--nord4);
@@ -152,15 +159,22 @@
}
@media (prefers-color-scheme: dark) {
.image-upload {
:global(:root:not([data-theme="light"])) .image-upload {
background-color: var(--nord2);
border-color: var(--nord3);
}
.image-upload:hover {
:global(:root:not([data-theme="light"])) .image-upload:hover {
background-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .image-upload {
background-color: var(--nord2);
border-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .image-upload:hover {
background-color: var(--nord3);
}
.upload-label {
cursor: pointer;
@@ -183,18 +197,27 @@
}
@media (prefers-color-scheme: dark) {
.upload-content svg {
:global(:root:not([data-theme="light"])) .upload-content svg {
color: var(--nord4);
}
.upload-content p {
:global(:root:not([data-theme="light"])) .upload-content p {
color: var(--font-default-dark);
}
.upload-content small {
:global(:root:not([data-theme="light"])) .upload-content small {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .upload-content svg {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .upload-content p {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .upload-content small {
color: var(--nord4);
}
.image-preview {
text-align: center;
@@ -240,10 +263,13 @@
}
@media (prefers-color-scheme: dark) {
.receipt-preview {
:global(:root:not([data-theme="light"])) .receipt-preview {
border-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .receipt-preview {
border-color: var(--nord2);
}
.image-actions {
display: flex;
+63 -24
View File
@@ -168,40 +168,51 @@
}
.language-button{
width: auto;
padding: 0.5rem 1rem;
border-radius: 8px;
background-color: var(--nord3);
color: white;
font-size: 0.9rem;
font-weight: 600;
padding: 0.3em 0.6em;
border-radius: 100px;
background: transparent;
color: var(--nav-text, rgba(255,255,255,0.6));
font-size: 0.75rem;
font-weight: 700;
cursor: pointer;
transition: background-color 100ms;
border: none;
transition: all 150ms;
border: 1px solid var(--nav-btn-border, rgba(255,255,255,0.2));
}
.language-button:hover{
background-color: var(--nord2);
color: var(--nav-text-hover, white);
border-color: var(--nav-btn-border-hover, rgba(255,255,255,0.4));
background: var(--nav-hover-bg, rgba(255,255,255,0.1));
}
.language-options{
--bg_color: var(--nord3);
--bg_color: rgba(46, 52, 64, 0.95);
--opt-text: rgba(255,255,255,0.7);
--opt-text-hover: white;
--opt-hover-bg: rgba(255,255,255,0.1);
--opt-active-bg: rgba(136, 192, 208, 0.25);
--opt-border: rgba(255,255,255,0.08);
box-sizing: border-box;
border-radius: 5px;
border-radius: 8px;
position: absolute;
right: 0;
top: calc(100% + 10px);
background-color: var(--bg_color);
width: 10ch;
padding: 0.5rem;
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
width: 8ch;
padding: 0.35rem;
z-index: 1000;
display: none;
border: 1px solid var(--opt-border);
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
}
.language-options::after {
content: "";
border: 10px solid transparent;
border: 8px solid transparent;
border-bottom-color: var(--bg_color);
border-top: 0;
position: absolute;
top: -10px;
right: 1rem;
top: -8px;
right: 0.8rem;
}
/* Show via JS toggle */
.language-options.open {
@@ -215,26 +226,54 @@
display: block;
width: 100%;
background-color: transparent;
color: white;
color: var(--opt-text);
border: none;
padding: 0.5rem;
padding: 0.4rem 0.5rem;
margin: 0;
border-radius: 4px;
border-radius: 6px;
cursor: pointer;
font-size: 1rem;
font-size: 0.8rem;
text-align: left;
text-decoration: none;
transition: background-color 100ms;
transition: all 100ms;
box-sizing: border-box;
}
.language-options a:hover{
background-color: var(--nord2);
background: var(--opt-hover-bg);
color: var(--opt-text-hover);
}
.language-options a.active{
background-color: var(--nord8);
color: var(--nord0);
background: var(--opt-active-bg);
color: var(--opt-text-hover);
font-weight: 700;
}
@media (prefers-color-scheme: dark) {
.language-options {
--bg_color: rgba(20, 20, 20, 0.92);
}
}
:global(:root[data-theme="dark"]) .language-options {
--bg_color: rgba(20, 20, 20, 0.92);
}
/* Light mode dropdown */
@media (prefers-color-scheme: light) {
:global(:root:not([data-theme])) .language-options {
--bg_color: rgba(255, 255, 255, 0.95);
--opt-text: rgba(0,0,0,0.6);
--opt-text-hover: var(--nord0);
--opt-hover-bg: rgba(0,0,0,0.06);
--opt-active-bg: rgba(94, 129, 172, 0.15);
--opt-border: rgba(0,0,0,0.08);
}
}
:global(:root[data-theme="light"]) .language-options {
--bg_color: rgba(255, 255, 255, 0.95);
--opt-text: rgba(0,0,0,0.6);
--opt-text-hover: var(--nord0);
--opt-hover-bg: rgba(0,0,0,0.06);
--opt-active-bg: rgba(94, 129, 172, 0.15);
--opt-border: rgba(0,0,0,0.08);
}
</style>
<div class="language-selector">
+86 -60
View File
@@ -1,34 +1,20 @@
<style>
:global(.links_grid a:nth-child(4n)),
:global(.links_grid a:nth-child(4n) svg:not(.lock-icon)){
background-color: var(--nord4);
fill: var(--nord11);
}
:global(.links_grid a:nth-child(4n+1)),
:global(.links_grid a:nth-child(4n+1) svg:not(.lock-icon)){
background-color: var(--nord6);
fill: var(--nord10);
}
:global(.links_grid a:nth-child(4n+2)){
background-color: var(--nord5);
}
:global(.links_grid a:nth-child(4n+3)){
background-color: var(--nord5);
}
.links_grid {
/* Light mode card palette */
--card-bg-a: var(--nord6);
--card-bg-b: var(--nord5);
--card-bg-c: var(--nord6);
--card-bg-d: var(--nord5);
--card-fill-a: var(--nord11);
--card-fill-b: var(--nord10);
--card-fill-c: var(--nord0);
--card-fill-d: var(--nord0);
--card-text: var(--nord0);
--card-shadow: rgba(0,0,0,0.04);
--card-shadow-hover: rgba(0,0,0,0.1);
--card-lock: var(--nord3);
:global(a){
text-decoration: unset;
color: var(--nord0);
transition: var(--transition-normal);
}
:global(.links_grid a:hover){
box-shadow: 1em 1em 2em 1em rgba(0,0,0, 0.3);
}
:global(.links_grid a){
box-shadow: 0.2em 0.2em 1em 1em rgba(0,0,0, 0.1);
}
.links_grid{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(250px, calc(50% - 1rem)), 1fr));
gap: 2rem;
@@ -36,27 +22,96 @@
margin-inline: auto;
padding: 2rem 1rem;
}
@media (prefers-color-scheme: dark) {
.links_grid {
--card-bg-a: #1a1a1a;
--card-bg-b: #1a1a1a;
--card-bg-c: var(--nord1);
--card-bg-d: #000;
--card-fill-a: var(--nord11);
--card-fill-b: var(--nord9);
--card-fill-c: var(--nord8);
--card-fill-d: var(--nord7);
--card-text: white;
--card-shadow: rgba(0,0,0,0.08);
--card-shadow-hover: rgba(0,0,0,0.15);
--card-lock: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .links_grid {
--card-bg-a: #1a1a1a;
--card-bg-b: #1a1a1a;
--card-bg-c: var(--nord1);
--card-bg-d: #000;
--card-fill-a: var(--nord11);
--card-fill-b: var(--nord9);
--card-fill-c: var(--nord8);
--card-fill-d: var(--nord7);
--card-text: white;
--card-shadow: rgba(0,0,0,0.08);
--card-shadow-hover: rgba(0,0,0,0.15);
--card-lock: var(--nord3);
}
:global(:root[data-theme="light"]) .links_grid {
--card-bg-a: var(--nord6);
--card-bg-b: var(--nord5);
--card-bg-c: var(--nord6);
--card-bg-d: var(--nord5);
--card-fill-a: var(--nord11);
--card-fill-b: var(--nord10);
--card-fill-c: var(--nord0);
--card-fill-d: var(--nord0);
--card-text: var(--nord0);
--card-shadow: rgba(0,0,0,0.04);
--card-shadow-hover: rgba(0,0,0,0.1);
--card-lock: var(--nord3);
}
:global(.links_grid a:nth-child(4n)),
:global(.links_grid a:nth-child(4n) svg:not(.lock-icon)){
background-color: var(--card-bg-a);
fill: var(--card-fill-a);
}
:global(.links_grid a:nth-child(4n+1)),
:global(.links_grid a:nth-child(4n+1) svg:not(.lock-icon)){
background-color: var(--card-bg-b);
fill: var(--card-fill-b);
}
:global(.links_grid a:nth-child(4n+2)),
:global(.links_grid a:nth-child(4n+2) svg:not(.lock-icon)){
background-color: var(--card-bg-c);
fill: var(--card-fill-c);
}
:global(.links_grid a:nth-child(4n+3)),
:global(.links_grid a:nth-child(4n+3) svg:not(.lock-icon)){
background-color: var(--card-bg-d);
fill: var(--card-fill-d);
}
:global(.links_grid a){
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-decoration: unset;
color: var(--nord0);
color: var(--card-text);
transition: var(--transition-normal);
width: 100%;
padding: 1rem;
position: relative;
box-shadow: 0 0.1em 0.5em 0 var(--card-shadow);
}
:global(.links_grid a:hover){
box-shadow: 0 0.2em 1em 0 var(--card-shadow-hover);
scale: 1.02;
}
:global(.links_grid a :is(svg, img)){
height: 120px;
fill: var(--nord0);
}
:global(.links_grid h3){
font-size: 1.5rem;
color: var(--card-text);
}
:global(.links_grid a .lock-icon){
position: absolute;
@@ -64,7 +119,7 @@
right: 0.5rem;
width: 1.5rem;
height: 1.5rem;
fill: var(--nord3);
fill: var(--card-lock);
opacity: 0.5;
}
@@ -109,35 +164,6 @@
right: 0.3rem;
}
}
@media (prefers-color-scheme: dark){
:global(.links_grid h3){
color: white;
}
:global(.links_grid a .lock-icon){
fill: var(--nord3);
}
:global(.links_grid a:nth-child(4n)),
:global(.links_grid a:nth-child(4n) svg:not(.lock-icon)){
background-color: var(--nord6-dark);
fill: var(--nord11);
}
:global(.links_grid a:nth-child(4n+1)),
:global(.links_grid a:nth-child(4n+1) svg:not(.lock-icon)){
background-color: var(--accent-dark);
fill: var(--nord9);
}
:global(.links_grid a:nth-child(4n+2)),
:global(.links_grid a:nth-child(4n+2) svg:not(.lock-icon)){
background-color: var(--nord1);
fill: var(--nord8);
}
:global(.links_grid a:nth-child(4n+3)),
:global(.links_grid a:nth-child(4n+3) svg:not(.lock-icon)){
background-color: var(--background-dark);
fill: var(--nord7);
}
}
</style>
<div class=links_grid>
+12 -1
View File
@@ -4,6 +4,14 @@
:root{
--icon_fill: var(--nord4);
}
@media (prefers-color-scheme: light) {
:global(:root:not([data-theme])) {
--icon_fill: var(--nord1);
}
}
:global(:root[data-theme="light"]) {
--icon_fill: var(--nord1);
}
svg{
transition: var(--transition-fast);
height: var(--symbol-size, 3em);
@@ -29,7 +37,7 @@
</style>
<svg
viewBox="0 0 45.742326 80.310541"
viewBox="0 0 330 80.310541"
version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g class=stroke
@@ -75,4 +83,7 @@
<path class=fill
d="M 0,0 -9.323,10.862 -3.185,17.76 0,21.339 3.173,17.774 9.324,10.862 Z M 41.228,66.513 C 41.168,66.275 38.492,57.729 32.099,49.53 28.9,45.41 24.801,41.388 19.697,38.388 15.112,35.701 9.727,33.802 3.198,33.324 L 0,36.917 -3.195,33.326 c -6.641,0.491 -12.102,2.451 -16.739,5.216 -7.724,4.607 -13.143,11.62 -16.561,17.559 -1.71,2.961 -2.918,5.631 -3.685,7.529 -0.383,0.949 -0.657,1.703 -0.83,2.204 -0.087,0.251 -0.148,0.438 -0.185,0.554 l -0.037,0.12 -0.006,0.017 -1.095,3.699 H -63.598 V 59.868 h 13.769 c 1.509,-3.763 4.398,-9.908 9.196,-16.216 3.801,-4.982 8.828,-10.072 15.38,-13.996 4.034,-2.422 8.662,-4.371 13.847,-5.556 l -3.872,-4.351 -7.799,-8.764 11.537,-13.441 c -5.22,-1.21 -9.868,-3.199 -13.916,-5.657 -9.751,-5.918 -16.085,-14.346 -20.051,-21.22 -2.011,-3.498 -3.414,-6.613 -4.323,-8.872 h -13.768 v -10.356 h 21.265 l 1.097,3.704 c 0.051,0.212 2.714,8.708 9.07,16.892 3.177,4.106 7.248,8.124 12.313,11.137 4.521,2.682 9.822,4.602 16.234,5.143 L 0,-15.9 l 3.619,4.215 c 6.533,-0.549 11.913,-2.527 16.488,-5.287 7.663,-4.624 13.036,-11.615 16.424,-17.525 1.694,-2.946 2.891,-5.601 3.652,-7.486 0.38,-0.943 0.651,-1.693 0.822,-2.19 0.085,-0.249 0.146,-0.435 0.183,-0.55 l 0.037,-0.119 0.004,-0.016 1.094,-3.703 h 21.268 v 10.356 H 49.825 c -1.499,3.743 -4.361,9.841 -9.105,16.111 -3.768,4.964 -8.752,10.044 -15.248,13.981 -4.052,2.46 -8.703,4.452 -13.928,5.661 l 11.534,13.437 -7.8,8.765 -3.867,4.345 c 5.185,1.183 9.812,3.13 13.845,5.55 9.835,5.899 16.218,14.364 20.21,21.275 2.032,3.529 3.447,6.672 4.36,8.948 H 63.591 V 70.224 H 42.323 Z"
transform="matrix(0.35277777,0,0,-0.35277777,23.308833,63.179301)" />
<path class=fill
d="m 63.34524,67.259285 h 13.664006 c 7.392004,0 11.573339,-0.821334 15.082674,-2.912001 3.882669,-2.389335 6.197336,-7.242671 6.197336,-12.91734 0,-6.79467 -2.837334,-10.901338 -9.258671,-13.58934 4.256002,-2.389334 6.12267,-5.973336 6.12267,-11.424005 0,-4.778669 -1.792001,-8.810671 -4.928002,-11.125339 -3.136002,-2.240001 -7.242671,-3.210668 -13.962674,-3.210668 H 63.34524 Z m 5.525336,-5.002669 V 40.827272 h 6.57067 c 6.496003,0 9.781338,0.448001 12.096005,1.568001 3.285335,1.642668 5.152003,4.928002 5.152003,9.333338 0,3.808002 -1.717334,7.168003 -4.330669,8.512004 -2.613335,1.418667 -6.34667,2.016001 -11.946672,2.016001 z m 0,-26.432013 V 17.083261 h 6.645336 c 5.67467,0 8.736004,0.522667 10.826672,1.941334 1.941334,1.269334 3.210668,4.181336 3.210668,7.466671 0,3.808001 -1.493334,6.645336 -4.256002,7.91467 -2.314668,1.045334 -4.704002,1.418667 -9.706671,1.418667 z M 125.09456,25.445932 c -12.17067,0 -21.42935,9.184004 -21.42935,21.130676 0,12.618673 9.18401,21.653344 21.87735,21.653344 11.94667,0 20.75734,-9.034671 20.75734,-21.28001 0,-12.469339 -8.88534,-21.50401 -21.20534,-21.50401 z m 0,5.077335 c 9.03467,0 15.60534,6.944004 15.60534,16.501342 0,9.408004 -6.42134,16.128007 -15.30668,16.128007 -9.408,0 -16.128,-6.79467 -16.128,-16.426674 0,-9.258671 6.79467,-16.202675 15.82934,-16.202675 z m 63.46674,24.714679 c -4.256,5.674669 -8.13867,7.91467 -14.03734,7.91467 -9.10933,0 -16.352,-7.168003 -16.352,-16.277341 0,-9.184004 7.09333,-16.352008 16.20267,-16.352008 6.048,0 11.05067,2.912002 14.18667,8.288004 h 6.19734 C 191.4733,30.597934 183.6333,25.445932 174.4493,25.445932 c -12.24534,0 -21.87735,9.408004 -21.87735,21.28001 0,12.170672 9.70667,21.50401 22.25068,21.50401 5.07734,0 9.78134,-1.568001 13.58934,-4.629335 2.61333,-2.090668 4.18134,-4.106669 6.42134,-8.362671 z m 13.66395,12.021339 h 5.52534 v -8.437337 l 6.42133,-7.914671 13.58934,16.352008 h 6.86934 L 217.68126,46.949942 233.58527,26.416599 H 226.7906 L 207.75059,51.205944 V 12.080592 h -5.52534 z m 76.38406,-18.592009 c 0,-5.600003 -0.74667,-9.034671 -2.76267,-12.618673 -3.65867,-6.570669 -10.752,-10.602671 -18.59201,-10.602671 -11.872,0 -21.13068,9.333337 -21.13068,21.205343 0,12.096006 9.48268,21.578677 21.57868,21.578677 8.88534,0 16.87468,-5.749336 19.86134,-14.410673 h -5.74933 c -2.31467,5.600002 -8.06401,9.333337 -14.26134,9.333337 -8.43734,0 -15.45601,-6.421336 -15.90401,-14.48534 z m -36.81069,-5.002669 c 1.49334,-7.840004 7.69067,-13.14134 15.45601,-13.14134 7.91467,0 13.88801,4.928003 15.82934,13.14134 z m 44.42666,23.594678 h 5.52534 V 44.784608 c 0,-4.554669 0.59733,-6.944004 2.16533,-9.258671 2.16534,-3.136002 5.97334,-5.00267 10.30401,-5.00267 4.032,0 7.69067,1.642668 9.93067,4.405336 1.94133,2.538668 2.688,5.525336 2.688,10.901338 v 21.429344 h 5.52533 V 45.829941 c 0,-6.869336 -0.97066,-10.528005 -3.584,-14.03734 -3.21067,-4.106668 -8.13867,-6.346669 -13.888,-6.346669 -5.37601,0 -9.70668,2.016001 -13.14134,6.272003 v -5.301336 h -5.52534 z"
aria-label="Bocken"/>
</svg>
+38
View File
@@ -0,0 +1,38 @@
<script>
import { themeStore } from '$lib/stores/theme.svelte';
import { Sun, Moon, SunMoon } from 'lucide-svelte';
</script>
<style>
button {
display: flex;
align-items: center;
justify-content: center;
padding: 0.3em;
border-radius: 100px;
background: transparent;
color: var(--nav-text);
cursor: pointer;
transition: all 150ms;
border: 1px solid var(--nav-btn-border);
}
button:hover {
color: var(--nav-text-hover);
border-color: var(--nav-btn-border-hover);
background: var(--nav-hover-bg);
}
</style>
<button
onclick={() => themeStore.cycle()}
aria-label="Toggle theme ({themeStore.theme})"
title="Theme: {themeStore.theme}"
>
{#if themeStore.theme === 'light'}
<Sun size={14} strokeWidth={2} />
{:else if themeStore.theme === 'dark'}
<Moon size={14} strokeWidth={2} />
{:else}
<SunMoon size={14} strokeWidth={2} />
{/if}
</button>
+13 -5
View File
@@ -1,5 +1,5 @@
<script lang="ts">
let { checked = $bindable(false), label = "", accentColor = "var(--nord14)", href = undefined as string | undefined } = $props<{ checked?: boolean, label?: string, accentColor?: string, href?: string }>();
let { checked = $bindable(false), label = "", accentColor = "var(--color-primary)", href = undefined as string | undefined } = $props<{ checked?: boolean, label?: string, accentColor?: string, href?: string }>();
</script>
<style>
@@ -19,10 +19,14 @@
}
@media(prefers-color-scheme: light) {
.toggle-wrapper label,
.toggle-wrapper a {
:global(:root:not([data-theme="dark"])) .toggle-wrapper label,
:global(:root:not([data-theme="dark"])) .toggle-wrapper a {
color: var(--nord2);
}
}
:global(:root[data-theme="light"]) .toggle-wrapper label,
:global(:root[data-theme="light"]) .toggle-wrapper a {
color: var(--nord2);
}
.toggle-wrapper span {
@@ -49,11 +53,15 @@
}
@media(prefers-color-scheme: light) {
.toggle-track,
.toggle-wrapper input[type="checkbox"] {
:global(:root:not([data-theme="dark"])) .toggle-track:not(.checked),
:global(:root:not([data-theme="dark"])) .toggle-wrapper input[type="checkbox"]:not(:checked) {
background: var(--nord4);
}
}
:global(:root[data-theme="light"]) .toggle-track:not(.checked),
:global(:root[data-theme="light"]) .toggle-wrapper input[type="checkbox"]:not(:checked) {
background: var(--nord4);
}
.toggle-track.checked,
.toggle-wrapper input[type="checkbox"]:checked {
-11
View File
@@ -155,17 +155,6 @@ h2 + p{
left: 50%;
margin-left: -20px;
}
button{
margin-bottom: 2rem;
}
button::before{
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
background: inherit;
z-index: 20;
}
}
</style>
+17 -2
View File
@@ -300,7 +300,7 @@
onMount(() => {
createChart();
// Watch for theme changes
// Watch for theme changes (both media query and data-theme attribute)
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleThemeChange = () => {
setTimeout(createChart, 100); // Small delay to let CSS variables update
@@ -308,8 +308,19 @@
mediaQuery.addEventListener('change', handleThemeChange);
// Also watch for data-theme attribute changes on <html>
const themeObserver = new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
handleThemeChange();
}
}
});
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
return () => {
mediaQuery.removeEventListener('change', handleThemeChange);
themeObserver.disconnect();
if (chart) {
chart.destroy();
}
@@ -331,11 +342,15 @@
}
@media (prefers-color-scheme: dark) {
.chart-container {
:global(:root:not([data-theme="light"])) .chart-container {
background: var(--nord1);
border-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .chart-container {
background: var(--nord1);
border-color: var(--nord2);
}
@media (max-width: 600px) {
.chart-container {
+95 -22
View File
@@ -481,101 +481,174 @@
}
@media (prefers-color-scheme: dark) {
.panel-content {
:global(:root:not([data-theme="light"])) .panel-content {
background: var(--nord1);
}
.panel-header {
:global(:root:not([data-theme="light"])) .panel-header {
background: var(--nord2);
border-bottom-color: var(--nord3);
}
.panel-header h2 {
:global(:root:not([data-theme="light"])) .panel-header h2 {
color: var(--font-default-dark);
}
.close-button {
:global(:root:not([data-theme="light"])) .close-button {
color: var(--nord4);
}
.close-button:hover {
:global(:root:not([data-theme="light"])) .close-button:hover {
background: var(--nord3);
color: var(--font-default-dark);
}
.error {
:global(:root:not([data-theme="light"])) .error {
background-color: var(--accent-dark);
}
.payment-header {
:global(:root:not([data-theme="light"])) .payment-header {
background: linear-gradient(135deg, var(--nord2), var(--nord3));
}
.title-section h1 {
:global(:root:not([data-theme="light"])) .title-section h1 {
color: var(--font-default-dark);
}
.receipt-image img {
:global(:root:not([data-theme="light"])) .receipt-image img {
border-color: var(--nord2);
}
.label {
:global(:root:not([data-theme="light"])) .label {
color: var(--nord4);
}
.value {
:global(:root:not([data-theme="light"])) .value {
color: var(--font-default-dark);
}
.description {
:global(:root:not([data-theme="light"])) .description {
border-top-color: var(--nord2);
}
.description h3 {
:global(:root:not([data-theme="light"])) .description h3 {
color: var(--font-default-dark);
}
.description p {
:global(:root:not([data-theme="light"])) .description p {
color: var(--nord5);
}
.splits-section {
:global(:root:not([data-theme="light"])) .splits-section {
border-top-color: var(--nord2);
}
.splits-section h3 {
:global(:root:not([data-theme="light"])) .splits-section h3 {
color: var(--font-default-dark);
}
.split-item {
:global(:root:not([data-theme="light"])) .split-item {
background: var(--nord2);
border-color: var(--nord3);
}
.split-item.current-user {
:global(:root:not([data-theme="light"])) .split-item.current-user {
background: var(--nord3);
border-color: var(--blue);
}
.username {
:global(:root:not([data-theme="light"])) .username {
color: var(--font-default-dark);
}
.panel-actions {
:global(:root:not([data-theme="light"])) .panel-actions {
background: var(--nord2);
border-top-color: var(--nord3);
}
.btn-secondary {
:global(:root:not([data-theme="light"])) .btn-secondary {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.btn-secondary:hover {
:global(:root:not([data-theme="light"])) .btn-secondary:hover {
background-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .panel-content {
background: var(--nord1);
}
:global(:root[data-theme="dark"]) .panel-header {
background: var(--nord2);
border-bottom-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .panel-header h2 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .close-button {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .close-button:hover {
background: var(--nord3);
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .error {
background-color: var(--accent-dark);
}
:global(:root[data-theme="dark"]) .payment-header {
background: linear-gradient(135deg, var(--nord2), var(--nord3));
}
:global(:root[data-theme="dark"]) .title-section h1 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .receipt-image img {
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .label {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .value {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .description {
border-top-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .description h3 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .description p {
color: var(--nord5);
}
:global(:root[data-theme="dark"]) .splits-section {
border-top-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .splits-section h3 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .split-item {
background: var(--nord2);
border-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .split-item.current-user {
background: var(--nord3);
border-color: var(--blue);
}
:global(:root[data-theme="dark"]) .username {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .panel-actions {
background: var(--nord2);
border-top-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .btn-secondary {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .btn-secondary:hover {
background-color: var(--nord3);
}
@media (max-width: 768px) {
.panel-content {
@@ -239,15 +239,22 @@
}
@media (prefers-color-scheme: dark) {
.form-section {
:global(:root:not([data-theme="light"])) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
.form-section h2 {
:global(:root:not([data-theme="light"])) .form-section h2 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .form-section h2 {
color: var(--font-default-dark);
}
.form-group {
margin-bottom: 1rem;
@@ -261,10 +268,13 @@
}
@media (prefers-color-scheme: dark) {
label {
:global(:root:not([data-theme="light"])) label {
color: var(--nord5);
}
}
:global(:root[data-theme="dark"]) label {
color: var(--nord5);
}
select {
width: 100%;
@@ -284,12 +294,17 @@
}
@media (prefers-color-scheme: dark) {
select {
:global(:root:not([data-theme="light"])) select {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) select {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.proportional-splits, .personal-splits {
margin-top: 1rem;
@@ -304,11 +319,15 @@
}
@media (prefers-color-scheme: dark) {
.proportional-splits {
:global(:root:not([data-theme="light"])) .proportional-splits {
border-color: var(--nord3);
background-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .proportional-splits {
border-color: var(--nord3);
background-color: var(--nord2);
}
.proportional-splits h3, .personal-splits h3 {
margin-top: 0;
@@ -317,10 +336,15 @@
}
@media (prefers-color-scheme: dark) {
.proportional-splits h3, .personal-splits h3 {
:global(:root:not([data-theme="light"])) .proportional-splits h3,
:global(:root:not([data-theme="light"])) .personal-splits h3 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .proportional-splits h3,
:global(:root[data-theme="dark"]) .personal-splits h3 {
color: var(--font-default-dark);
}
.personal-splits .description {
color: var(--nord2);
@@ -330,10 +354,13 @@
}
@media (prefers-color-scheme: dark) {
.personal-splits .description {
:global(:root:not([data-theme="light"])) .personal-splits .description {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .personal-splits .description {
color: var(--nord4);
}
.split-input {
display: flex;
@@ -365,12 +392,17 @@
}
@media (prefers-color-scheme: dark) {
.split-input input {
:global(:root:not([data-theme="light"])) .split-input input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .split-input input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.remainder-info {
margin-top: 1rem;
@@ -386,16 +418,24 @@
}
@media (prefers-color-scheme: dark) {
.remainder-info {
:global(:root:not([data-theme="light"])) .remainder-info {
background-color: var(--nord2);
border-color: var(--nord3);
}
.remainder-info.error {
:global(:root:not([data-theme="light"])) .remainder-info.error {
background-color: var(--accent-dark);
border-color: var(--red);
}
}
:global(:root[data-theme="dark"]) .remainder-info {
background-color: var(--nord2);
border-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .remainder-info.error {
background-color: var(--accent-dark);
border-color: var(--red);
}
.remainder-info span {
display: block;
@@ -418,11 +458,15 @@
}
@media (prefers-color-scheme: dark) {
.split-preview {
:global(:root:not([data-theme="light"])) .split-preview {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .split-preview {
background-color: var(--nord2);
border-color: var(--nord3);
}
.split-preview h3 {
margin-top: 0;
@@ -431,10 +475,13 @@
}
@media (prefers-color-scheme: dark) {
.split-preview h3 {
:global(:root:not([data-theme="light"])) .split-preview h3 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .split-preview h3 {
color: var(--font-default-dark);
}
.split-item {
display: flex;
@@ -454,10 +501,13 @@
}
@media (prefers-color-scheme: dark) {
.username {
:global(:root:not([data-theme="light"])) .username {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .username {
color: var(--font-default-dark);
}
.amount.positive {
color: var(--green);
+33 -7
View File
@@ -99,15 +99,22 @@
}
@media (prefers-color-scheme: dark) {
.form-section {
:global(:root:not([data-theme="light"])) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
.form-section h2 {
:global(:root:not([data-theme="light"])) .form-section h2 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .form-section {
background: var(--nord1);
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .form-section h2 {
color: var(--font-default-dark);
}
.users-list {
display: flex;
@@ -127,11 +134,15 @@
}
@media (prefers-color-scheme: dark) {
.user-item {
:global(:root:not([data-theme="light"])) .user-item {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .user-item {
background-color: var(--nord2);
border-color: var(--nord3);
}
.user-item.with-profile {
gap: 0.75rem;
@@ -143,10 +154,13 @@
}
@media (prefers-color-scheme: dark) {
.user-item .username {
:global(:root:not([data-theme="light"])) .user-item .username {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .user-item .username {
color: var(--font-default-dark);
}
.you-badge {
background-color: var(--blue);
@@ -165,11 +179,15 @@
}
@media (prefers-color-scheme: dark) {
.predefined-users {
:global(:root:not([data-theme="light"])) .predefined-users {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .predefined-users {
background-color: var(--nord2);
border-color: var(--nord3);
}
.predefined-note {
margin: 0 0 1rem 0;
@@ -179,10 +197,13 @@
}
@media (prefers-color-scheme: dark) {
.predefined-note {
:global(:root:not([data-theme="light"])) .predefined-note {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .predefined-note {
color: var(--nord4);
}
.remove-user {
background-color: var(--red);
@@ -223,12 +244,17 @@
}
@media (prefers-color-scheme: dark) {
.add-user input {
:global(:root:not([data-theme="light"])) .add-user input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .add-user input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.add-user button {
background-color: var(--blue);
+22 -17
View File
@@ -111,21 +111,13 @@
}
@media(prefers-color-scheme: light) {
.modal-backdrop {
:global(:root:not([data-theme="dark"])) .modal-backdrop {
background: rgba(255, 255, 255, 0.3);
}
@keyframes show-backdrop {
from {
backdrop-filter: blur(0px);
background: rgba(255, 255, 255, 0);
}
to {
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.3);
}
}
}
:global(:root[data-theme="light"]) .modal-backdrop {
background: rgba(255, 255, 255, 0.3);
}
.modal-content {
background: var(--nord0);
@@ -140,10 +132,13 @@
}
@media(prefers-color-scheme: light) {
.modal-content {
:global(:root:not([data-theme="dark"])) .modal-content {
background: var(--nord6);
}
}
:global(:root[data-theme="light"]) .modal-content {
background: var(--nord6);
}
.modal-header {
display: flex;
@@ -154,10 +149,13 @@
}
@media(prefers-color-scheme: light) {
.modal-header {
:global(:root:not([data-theme="dark"])) .modal-header {
border-bottom: 1px solid var(--nord4);
}
}
:global(:root[data-theme="light"]) .modal-header {
border-bottom: 1px solid var(--nord4);
}
.header-content {
flex: 1;
@@ -227,11 +225,15 @@
}
@media(prefers-color-scheme: light) {
.loading,
.error {
:global(:root:not([data-theme="dark"])) .loading,
:global(:root:not([data-theme="dark"])) .error {
color: var(--nord2);
}
}
:global(:root[data-theme="light"]) .loading,
:global(:root[data-theme="light"]) .error {
color: var(--nord2);
}
.error {
color: var(--nord11);
@@ -252,10 +254,13 @@
}
@media(prefers-color-scheme: light) {
.verse {
:global(:root:not([data-theme="dark"])) .verse {
color: var(--nord0);
}
}
:global(:root[data-theme="light"]) .verse {
color: var(--nord0);
}
.verse-number {
color: var(--nord10);
@@ -47,5 +47,4 @@
bind:checked={showBilingual}
{label}
{href}
accentColor="var(--nord14)"
/>
+4 -1
View File
@@ -34,9 +34,12 @@ svg {
}
@media(prefers-color-scheme: light) {
svg {
:global(:root:not([data-theme="dark"])) svg {
fill: var(--nord0);
}
}
:global(:root[data-theme="light"]) svg {
fill: var(--nord0);
}
:global(.mystery-button.selected) svg,
+10 -2
View File
@@ -154,14 +154,22 @@
}
}
@media (prefers-color-scheme: light) {
.sticky-image-layout:not(.overlay) .image-wrap-desktop {
:global(:root:not([data-theme="dark"])) .sticky-image-layout:not(.overlay) .image-wrap-desktop {
background-color: var(--nord5);
}
}
:global(:root[data-theme="light"]) .sticky-image-layout:not(.overlay) .image-wrap-desktop {
background-color: var(--nord5);
}
@media (prefers-color-scheme: light) and (min-width: 1024px) {
.sticky-image-layout:not(.overlay) .image-wrap-desktop {
:global(:root:not([data-theme="dark"])) .sticky-image-layout:not(.overlay) .image-wrap-desktop {
background-color: transparent;
}
}
@media (min-width: 1024px) {
:global(:root[data-theme="light"]) .sticky-image-layout:not(.overlay) .image-wrap-desktop {
background-color: transparent;
}
}
@media (min-width: 1400px) {
.sticky-image-layout:not(.overlay)::before {
+14 -4
View File
@@ -51,7 +51,8 @@ async function pray() {
<StreakAura value={displayLength} {burst} />
<span class="streak-label">{labels.days}</span>
</div>
<form method="POST" action="?/pray" onsubmit={(e) => { e.preventDefault(); pray(); }}>
<form method="POST" action="?/pray" onsubmit={(e) => { e.preventDefault(); pray(); }
}>
<button
class="streak-button"
type="submit"
@@ -79,9 +80,12 @@ async function pray() {
}
@media (prefers-color-scheme: light) {
.streak-container {
:global(:root:not([data-theme="dark"])) .streak-container {
background: var(--nord5);
}
}
:global(:root[data-theme="light"]) .streak-container {
background: var(--nord5);
}
.streak-display {
@@ -97,9 +101,12 @@ async function pray() {
}
@media (prefers-color-scheme: light) {
.streak-label {
:global(:root:not([data-theme="dark"])) .streak-label {
color: var(--nord3);
}
}
:global(:root[data-theme="light"]) .streak-label {
color: var(--nord3);
}
.streak-button {
@@ -135,8 +142,11 @@ async function pray() {
}
@media (prefers-color-scheme: light) {
.streak-button:disabled {
:global(:root:not([data-theme="dark"])) .streak-button:disabled {
background: var(--nord4);
}
}
:global(:root[data-theme="light"]) .streak-button:disabled {
background: var(--nord4);
}
</style>
+14 -6
View File
@@ -70,14 +70,22 @@
/* === LIGHT MODE === */
@media (prefers-color-scheme: light) {
.prayer-wrapper :global(v:lang(la)),
.prayer-wrapper.vernacular-primary :global(v:lang(de)),
.prayer-wrapper.vernacular-primary :global(v:lang(en)),
.prayer-wrapper.monolingual :global(v:not(:lang(la))),
.prayer-wrapper.no-latin :global(v:lang(de)),
.prayer-wrapper.no-latin :global(v:lang(en)) {
:global(:root:not([data-theme="dark"])) .prayer-wrapper :global(v:lang(la)),
:global(:root:not([data-theme="dark"])) .prayer-wrapper.vernacular-primary :global(v:lang(de)),
:global(:root:not([data-theme="dark"])) .prayer-wrapper.vernacular-primary :global(v:lang(en)),
:global(:root:not([data-theme="dark"])) .prayer-wrapper.monolingual :global(v:not(:lang(la))),
:global(:root:not([data-theme="dark"])) .prayer-wrapper.no-latin :global(v:lang(de)),
:global(:root:not([data-theme="dark"])) .prayer-wrapper.no-latin :global(v:lang(en)) {
color: black;
}
}
:global(:root[data-theme="light"]) .prayer-wrapper :global(v:lang(la)),
:global(:root[data-theme="light"]) .prayer-wrapper.vernacular-primary :global(v:lang(de)),
:global(:root[data-theme="light"]) .prayer-wrapper.vernacular-primary :global(v:lang(en)),
:global(:root[data-theme="light"]) .prayer-wrapper.monolingual :global(v:not(:lang(la))),
:global(:root[data-theme="light"]) .prayer-wrapper.no-latin :global(v:lang(de)),
:global(:root[data-theme="light"]) .prayer-wrapper.no-latin :global(v:lang(en)) {
color: black;
}
/* === INLINE / RUBRIC TEXT === */
@@ -198,9 +198,12 @@ dialog h2 {
}
@media (prefers-color-scheme: dark) {
.selector-content {
:global(:root:not([data-theme="light"])) .selector-content {
background-color: var(--nord1);
}
}
:global(:root[data-theme="dark"]) .selector-content {
background-color: var(--nord1);
}
</style>
@@ -115,10 +115,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
+5 -18
View File
@@ -101,21 +101,21 @@
font-size: 0.7rem;
padding: 0.1rem 0.4rem;
border-radius: var(--radius-pill);
background-color: var(--nord5);
color: var(--nord3);
background-color: var(--color-bg-elevated);
color: var(--color-text-secondary);
text-decoration: none;
cursor: pointer;
transition: transform var(--transition-fast), background-color var(--transition-fast), box-shadow var(--transition-fast), color var(--transition-fast);
box-shadow: var(--shadow-sm);
box-shadow: none;
border: none;
display: inline-block;
}
.tag:hover,
.tag:focus-visible {
transform: scale(1.05);
background-color: var(--nord8);
background-color: var(--color-primary);
box-shadow: var(--shadow-hover);
color: var(--nord0);
color: var(--color-text-on-primary);
}
@media (min-width: 600px) {
.tag {
@@ -123,19 +123,6 @@
padding: 0.15rem 0.55rem;
}
}
@media (prefers-color-scheme: dark) {
.tag,
.tag:visited,
.tag:link {
background-color: var(--nord0);
color: var(--nord4);
}
.tag:hover,
.tag:focus-visible {
background-color: var(--nord8);
color: var(--nord0);
}
}
.icon {
position: absolute;
top: -1.2em;
@@ -635,13 +635,19 @@ h3{
fill: var(--nord1);
}
@media (prefers-color-scheme: dark){
.button_arrow{
:global(:root:not([data-theme="light"])) .button_arrow {
fill: var(--nord4);
}
.list_wrapper p[contenteditable]{
:global(:root:not([data-theme="light"])) .list_wrapper p[contenteditable] {
background-color: var(--accent-dark);
}
}
:global(:root[data-theme="dark"]) .button_arrow {
fill: var(--nord4);
}
:global(:root[data-theme="dark"]) .list_wrapper p[contenteditable] {
background-color: var(--accent-dark);
}
/* Styling for converted div-to-button elements */
@@ -688,12 +694,18 @@ h3{
}
@media (prefers-color-scheme: dark) {
.reference-container {
:global(:root:not([data-theme="light"])) .reference-container {
background-color: var(--nord1);
}
.reference-badge {
:global(:root:not([data-theme="light"])) .reference-badge {
color: var(--nord6);
}
}
:global(:root[data-theme="dark"]) .reference-container {
background-color: var(--nord1);
}
:global(:root[data-theme="dark"]) .reference-badge {
color: var(--nord6);
}
.insert-base-recipe-button {
@@ -664,20 +664,29 @@ h3{
}
}
@media (prefers-color-scheme: dark){
.additional_info div{
:global(:root:not([data-theme="light"])) .additional_info div {
background-color: var(--accent-dark);
}
.instructions{
:global(:root:not([data-theme="light"])) .instructions {
background-color: var(--nord6-dark);
}
}
:global(:root[data-theme="dark"]) .additional_info div {
background-color: var(--accent-dark);
}
:global(:root[data-theme="dark"]) .instructions {
background-color: var(--nord6-dark);
}
.button_arrow{
fill: var(--nord1);
}
@media (prefers-color-scheme: dark){
.button_arrow{
:global(:root:not([data-theme="light"])) .button_arrow {
fill: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .button_arrow {
fill: var(--nord4);
}
/* Styling for converted div-to-button elements */
@@ -715,12 +724,18 @@ h3{
}
@media (prefers-color-scheme: dark) {
.reference-container {
:global(:root:not([data-theme="light"])) .reference-container {
background-color: var(--nord1);
}
.reference-badge {
:global(:root:not([data-theme="light"])) .reference-badge {
color: var(--nord6);
}
}
:global(:root[data-theme="dark"]) .reference-container {
background-color: var(--nord1);
}
:global(:root[data-theme="dark"]) .reference-badge {
color: var(--nord6);
}
.insert-base-recipe-button {
@@ -50,10 +50,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
@@ -50,9 +50,9 @@
.toggle-button {
display: none;
background: transparent;
color: var(--nord3);
color: var(--color-text-secondary);
padding: 0.5rem 0.8rem;
border: 1px solid var(--nord2);
border: 1px solid var(--color-border);
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
@@ -66,9 +66,9 @@
}
.toggle-button:hover {
background: var(--nord1);
color: var(--nord4);
border-color: var(--nord3);
background: var(--color-surface);
color: var(--color-text-primary);
border-color: var(--color-border-hover);
}
.arrow {
+5 -2
View File
@@ -13,10 +13,13 @@
box-shadow: 0em 0em 0.5em 0.2em rgba(0, 0, 0, 0.2);
}
@media (prefers-color-scheme: dark) {
a{
:global(:root:not([data-theme="light"])) a {
background-color: var(--accent-dark);
}
}
}
:global(:root[data-theme="dark"]) a {
background-color: var(--accent-dark);
}
a:hover{
--angle: 15deg;
animation: shake 0.5s ease forwards;
+5 -2
View File
@@ -107,10 +107,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
@@ -386,11 +386,12 @@ function adjust_amount(string, multiplier){
/* Hover scale override - larger than default */
.multipliers :is(button, form):is(:hover, :focus-within){
scale: 1.2;
background-color: var(--nord8);
background-color: var(--color-primary);
color: var(--color-text-on-primary);
}
.selected{
background-color: var(--nord9) !important;
color: white !important;
background-color: var(--color-primary) !important;
color: var(--color-text-on-primary) !important;
font-weight: bold;
scale: 1.2 !important;
}
@@ -453,8 +454,8 @@ function adjust_amount(string, multiplier){
display: none;
}
.cake-form-selected {
background-color: var(--nord9);
color: white;
background-color: var(--color-primary);
color: var(--color-text-on-primary);
font-weight: bold;
}
.cake-form-inputs {
@@ -467,7 +468,7 @@ function adjust_amount(string, multiplier){
.cake-form-num {
width: 3.5em;
padding: 0.2em 0.4em;
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
text-align: center;
font-size: inherit;
@@ -478,7 +479,7 @@ function adjust_amount(string, multiplier){
text-align: center;
margin-top: 0.4rem;
font-weight: bold;
color: var(--nord10);
color: var(--color-primary);
}
</style>
@@ -102,13 +102,13 @@ const labels = $derived({
<style>
ol li::marker{
font-weight: bold;
color: var(--blue);
color: var(--color-primary);
font-size: 1.2rem;
}
.instructions{
flex-basis: 0;
flex-grow: 2;
background-color: var(--nord5);
background-color: var(--color-bg-secondary);
padding-block: 1rem;
padding-inline: 2rem;
}
@@ -129,18 +129,10 @@ ol li::marker{
.additional_info > *{
flex-grow: 0;
padding: 1em;
background-color: #FAFAFE;
background-color: var(--color-bg-tertiary);
box-shadow: var(--shadow-md);
max-width: 30%
}
@media (prefers-color-scheme: dark){
.instructions{
background-color: var(--nord6-dark);
}
.additional_info > *{
background-color: var(--accent-dark);
}
}
@media screen and (max-width: 500px){
.additional_info > *{
max-width: 60%;
@@ -48,10 +48,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
@@ -70,10 +73,13 @@
}
@media (prefers-color-scheme: dark) {
.toggle-container {
:global(:root:not([data-theme="light"])) .toggle-container {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .toggle-container {
color: var(--nord6);
}
.toggle-switch {
position: relative;
@@ -115,10 +121,13 @@
}
@media (prefers-color-scheme: dark) {
.mode-label.active {
:global(:root:not([data-theme="light"])) .mode-label.active {
color: var(--nord8);
}
}
}
:global(:root[data-theme="dark"]) .mode-label.active {
color: var(--nord8);
}
.toggle-switch.or-mode + .mode-label.or {
color: var(--nord12);
@@ -135,7 +144,8 @@
onclick={() => checked = !checked}
role="button"
tabindex="0"
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); checked = !checked; } }}
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); checked = !checked; } }
}
>
<div class="toggle-knob"></div>
</div>
+5 -5
View File
@@ -307,14 +307,14 @@
input#search {
all: unset;
box-sizing: border-box;
background: var(--nord0);
color: #fff;
background: var(--color-surface);
color: var(--color-text-primary);
padding: 0.7rem 2rem;
border-radius: var(--radius-pill);
width: 100%;
}
input::placeholder{
color: var(--nord6);
color: var(--color-text-muted);
}
.search {
@@ -344,12 +344,12 @@ input::placeholder{
right: 0.5em;
width: 1.5em;
height: 1.5em;
color: var(--nord6);
color: var(--color-text-tertiary);
cursor: pointer;
transition: color 180ms ease-in-out;
}
.search-button:hover {
color: white;
color: var(--color-text-primary);
scale: 1.1 1.1;
}
.search-button:active{
@@ -101,10 +101,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
@@ -29,8 +29,8 @@
a.month{
text-decoration: unset;
border-radius: var(--radius-pill);
background-color: var(--blue);
color: var(--nord5);
background-color: var(--color-primary);
color: var(--color-text-on-primary);
padding: 0.5em;
transition: var(--transition-fast);
min-width: 4em;
@@ -40,7 +40,7 @@ a.month:hover,
.active
{
transform: scale(1.1,1.1) !important;
background-color: var(--red) !important;
background-color: var(--color-accent) !important;
}
.months{
display:flex;
+5 -2
View File
@@ -91,10 +91,13 @@
}
@media (prefers-color-scheme: dark) {
.filter-label {
:global(:root:not([data-theme="light"])) .filter-label {
color: var(--nord6);
}
}
}
:global(:root[data-theme="dark"]) .filter-label {
color: var(--nord6);
}
@media (max-width: 968px) {
.filter-label {
@@ -46,9 +46,9 @@
.section {
margin-bottom: -20vh;
margin-top: calc(-3.5rem - 12px);
transform-origin: center top;
transform: translateY(-1rem)
scaleY(calc(1 - var(--scale)));
transform: scaleY(calc(1 - var(--scale)));
}
.section > * {
@@ -67,7 +67,7 @@
align-items: center;
justify-content: center;
top: 0;
height: max(50dvh, 500px);
height: max(55dvh, 540px);
z-index: -10;
margin: 0;
}
@@ -78,8 +78,8 @@
left: 0;
right: 0;
margin-inline: auto;
width: min(1000px, 100dvw);
height: max(60dvh,600px);
width: min(calc(1000px + 2rem), 100dvw);
height: max(65dvh, 640px);
overflow: hidden;
}
@@ -87,8 +87,8 @@
display: block;
position: absolute;
top: 0;
width: min(1000px, 100dvw);
height: max(60dvh,600px);
width: min(calc(1000px + 2rem), 100dvw);
height: max(65dvh, 640px);
object-fit: cover;
object-position: 50% 20%;
}
+16 -4
View File
@@ -66,15 +66,24 @@
color: var(--nord0);
}
@media (prefers-color-scheme: dark) {
.link-pill {
:global(:root:not([data-theme="light"])) .link-pill {
background-color: var(--nord0);
color: var(--nord4);
}
.link-pill:hover,
.link-pill:focus-visible {
:global(:root:not([data-theme="light"])) .link-pill:hover,
:global(:root:not([data-theme="light"])) .link-pill:focus-visible {
background-color: var(--nord8);
color: var(--nord0);
}
}
:global(:root[data-theme="dark"]) .link-pill {
background-color: var(--nord0);
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .link-pill:hover,
:global(:root[data-theme="dark"]) .link-pill:focus-visible {
background-color: var(--nord8);
color: var(--nord0);
}
.notes {
font-size: 0.85rem;
@@ -86,9 +95,12 @@
overflow: hidden;
}
@media (prefers-color-scheme: dark) {
.notes {
:global(:root:not([data-theme="light"])) .notes {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .notes {
color: var(--nord4);
}
.card-btn {
position: absolute;
@@ -384,10 +384,14 @@
}
@media(prefers-color-scheme: light) {
.translation-approval {
:global(:root:not([data-theme="dark"])) .translation-approval {
background: var(--nord6);
border-color: var(--nord4);
}
}
:global(:root[data-theme="light"]) .translation-approval {
background: var(--nord6);
border-color: var(--nord4);
}
.header {
@@ -403,9 +407,12 @@
}
@media(prefers-color-scheme: light) {
.header h3 {
:global(:root:not([data-theme="dark"])) .header h3 {
color: var(--nord0);
}
}
:global(:root[data-theme="light"]) .header h3 {
color: var(--nord0);
}
.status-badge {
@@ -458,12 +465,18 @@
/* Fix button icon visibility in dark mode */
@media (prefers-color-scheme: dark) {
.list-wrapper :global(svg) {
:global(:root:not([data-theme="light"])) .list-wrapper :global(svg) {
fill: white !important;
}
.list-wrapper :global(.button_arrow) {
:global(:root:not([data-theme="light"])) .list-wrapper :global(.button_arrow) {
fill: var(--nord4) !important;
}
}
:global(:root[data-theme="dark"]) .list-wrapper :global(svg) {
fill: white !important;
}
:global(:root[data-theme="dark"]) .list-wrapper :global(.button_arrow) {
fill: var(--nord4) !important;
}
.column-header {
@@ -585,9 +598,12 @@ button:disabled {
}
@media(prefers-color-scheme: light) {
.idle-state {
:global(:root:not([data-theme="dark"])) .idle-state {
color: var(--nord2);
}
}
:global(:root[data-theme="light"]) .idle-state {
color: var(--nord2);
}
.idle-state p {
@@ -40,9 +40,12 @@
}
@media(prefers-color-scheme: light) {
.field-label {
:global(:root:not([data-theme="dark"])) .field-label {
color: var(--nord2);
}
}
:global(:root[data-theme="light"]) .field-label {
color: var(--nord2);
}
.field-value {
@@ -55,11 +58,16 @@
}
@media(prefers-color-scheme: light) {
.field-value {
:global(:root:not([data-theme="dark"])) .field-value {
background: var(--nord5);
color: var(--nord0);
border-color: var(--nord3);
}
}
:global(:root[data-theme="light"]) .field-value {
background: var(--nord5);
color: var(--nord0);
border-color: var(--nord3);
}
.field-value.readonly {
@@ -113,13 +121,19 @@ textarea.field-value {
}
@media(prefers-color-scheme: light) {
:global(.readonly-text strong) {
:global(:root:not([data-theme="dark"]) .readonly-text strong) {
color: var(--nord10);
}
:global(.readonly-text li) {
:global(:root:not([data-theme="dark"]) .readonly-text li) {
color: var(--nord2);
}
}
:global(:root[data-theme="light"]) :global(.readonly-text strong) {
color: var(--nord10);
}
:global(:root[data-theme="light"]) :global(.readonly-text li) {
color: var(--nord2);
}
</style>
+1 -1
View File
@@ -6,7 +6,7 @@
.action_button{
border: none;
cursor: pointer;
background-color: var(--red);
background-color: var(--color-accent);
transition: var(--transition-normal);
box-shadow: 0 0 1em 0.2em rgba(0,0,0,0.3);
padding: 1rem;
+1 -7
View File
@@ -6,7 +6,7 @@
top: -0.5em;
right: -0.5em;
padding: 0.25em;
background-color: var(--nord6);
background-color: var(--color-bg-tertiary);
}
.icon:focus {
@@ -14,12 +14,6 @@
rotate: var(--angle);
}
@media (prefers-color-scheme: dark) {
.icon {
background-color: var(--accent-dark);
}
}
/* Input-specific overrides */
input.icon {
z-index: 3;
+4 -16
View File
@@ -1,23 +1,11 @@
/* Shared link styling for recipe reference links in h3 elements */
h3 a {
color: var(--nord10);
color: var(--color-link);
text-decoration: underline;
text-decoration-color: var(--nord10);
text-decoration-color: var(--color-link);
}
h3 a:hover {
color: var(--nord9);
text-decoration-color: var(--nord9);
}
@media (prefers-color-scheme: dark) {
h3 a {
color: var(--nord8);
text-decoration-color: var(--nord8);
}
h3 a:hover {
color: var(--nord7);
text-decoration-color: var(--nord7);
}
color: var(--color-link-hover);
text-decoration-color: var(--color-link-hover);
}
+46
View File
@@ -0,0 +1,46 @@
import { browser } from '$app/environment';
export type Theme = 'system' | 'light' | 'dark';
const STORAGE_KEY = 'theme';
const CYCLE: Theme[] = ['system', 'light', 'dark'];
function applyTheme(theme: Theme) {
if (!browser) return;
if (theme === 'system') {
delete document.documentElement.dataset.theme;
} else {
document.documentElement.dataset.theme = theme;
}
}
function createTheme() {
let theme = $state<Theme>('system');
if (browser) {
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null;
if (stored && CYCLE.includes(stored)) {
theme = stored;
}
applyTheme(theme);
}
return {
get theme() { return theme; },
cycle() {
const next = CYCLE[(CYCLE.indexOf(theme) + 1) % CYCLE.length];
theme = next;
applyTheme(next);
if (browser) {
if (next === 'system') {
localStorage.removeItem(STORAGE_KEY);
} else {
localStorage.setItem(STORAGE_KEY, next);
}
}
}
};
}
export const themeStore = createTheme();