Polish planner icons and mobile theme controls

This commit is contained in:
2026-04-13 14:27:15 +02:00
parent 7faa65d6c9
commit d0d5bad803
15 changed files with 244 additions and 13 deletions
+9
View File
@@ -36,6 +36,14 @@ from .main import main_bp
WEEKDAY_NAMES = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"] WEEKDAY_NAMES = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"]
WEEKDAY_SHORT_NAMES = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"] WEEKDAY_SHORT_NAMES = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
DEFAULT_RELEASE_URL = "https://git.hnz.io/hnzio/nouri-App/releases" DEFAULT_RELEASE_URL = "https://git.hnz.io/hnzio/nouri-App/releases"
DAYPART_ICON_CLASSES = {
"breakfast": "icon-daypart-breakfast",
"morning-snack": "icon-daypart-morning-snack",
"lunch": "icon-daypart-lunch",
"afternoon-snack": "icon-daypart-afternoon-snack",
"dinner": "icon-daypart-dinner",
"late-snack": "icon-daypart-late-snack",
}
def load_secret_key(data_dir: Path) -> str: def load_secret_key(data_dir: Path) -> str:
@@ -149,6 +157,7 @@ def create_app() -> Flask:
"push_available": bool(app.config["VAPID_PUBLIC_KEY"] and app.config["VAPID_PRIVATE_KEY"]), "push_available": bool(app.config["VAPID_PUBLIC_KEY"] and app.config["VAPID_PRIVATE_KEY"]),
"weekday_name": lambda value: WEEKDAY_NAMES[value.weekday()], "weekday_name": lambda value: WEEKDAY_NAMES[value.weekday()],
"weekday_short_name": lambda value: WEEKDAY_SHORT_NAMES[value.weekday()], "weekday_short_name": lambda value: WEEKDAY_SHORT_NAMES[value.weekday()],
"daypart_icon_class": lambda slug: DAYPART_ICON_CLASSES.get(slug, "icon-calendar"),
"is_admin": lambda: bool(getattr(g, "user", None)) and g.user["role"] == "admin", "is_admin": lambda: bool(getattr(g, "user", None)) and g.user["role"] == "admin",
"asset_url": asset_url, "asset_url": asset_url,
"image_url": lambda filename, variant="md": image_url( "image_url": lambda filename, variant="md": image_url(
+197 -4
View File
@@ -101,7 +101,7 @@ button,
background: var(--accent); background: var(--accent);
color: white; color: white;
cursor: pointer; cursor: pointer;
transition: transform 160ms ease, background 160ms ease, border-color 160ms ease; transition: transform 160ms ease, background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
} }
button:focus-visible, button:focus-visible,
@@ -124,19 +124,64 @@ button:hover,
.button.secondary, .button.secondary,
button.secondary, button.secondary,
.ghost-button { .ghost-button {
background: transparent; background: linear-gradient(
180deg,
color-mix(in srgb, var(--surface-soft) 72%, #fff 28%),
color-mix(in srgb, var(--surface-strong) 82%, #fff 18%)
);
color: var(--text); color: var(--text);
border-color: var(--line); border-color: color-mix(in srgb, var(--accent) 34%, var(--line) 66%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.8),
0 8px 20px rgba(225, 181, 138, 0.12);
} }
.button.secondary:hover, .button.secondary:hover,
button.secondary:hover, button.secondary:hover,
.ghost-button:hover { .ghost-button:hover {
background: linear-gradient(
180deg,
color-mix(in srgb, var(--accent-soft) 58%, #fff 42%),
color-mix(in srgb, var(--surface-soft) 88%, #fff 12%)
);
border-color: color-mix(in srgb, var(--accent) 46%, var(--line) 54%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.84),
0 12px 28px rgba(212, 155, 104, 0.16);
}
[data-theme="dark"] button:not(.secondary):not(.ghost-button),
[data-theme="dark"] .button:not(.secondary):not(.ghost-button) {
background: #d7935f;
color: #201a17;
border-color: rgba(243, 177, 125, 0.28);
}
[data-theme="dark"] button:not(.secondary):not(.ghost-button):hover,
[data-theme="dark"] .button:not(.secondary):not(.ghost-button):hover {
background: #e0a270;
color: #181311;
}
[data-theme="dark"] .button.secondary,
[data-theme="dark"] button.secondary,
[data-theme="dark"] .ghost-button {
background: transparent;
color: var(--text);
border-color: var(--line);
box-shadow: none;
}
[data-theme="dark"] .button.secondary:hover,
[data-theme="dark"] button.secondary:hover,
[data-theme="dark"] .ghost-button:hover {
background: var(--accent-soft); background: var(--accent-soft);
border-color: rgba(243, 177, 125, 0.2);
box-shadow: none;
} }
.page-shell { .page-shell {
width: min(1320px, calc(100% - 2rem)); width: min(1680px, calc(100% - 2rem));
margin: 1rem auto 2rem; margin: 1rem auto 2rem;
} }
@@ -233,6 +278,7 @@ h3,
} }
.site-nav a { .site-nav a {
flex: 0 0 auto;
padding: 0.55rem 0.85rem; padding: 0.55rem 0.85rem;
border-radius: 999px; border-radius: 999px;
color: var(--muted); color: var(--muted);
@@ -265,6 +311,8 @@ h3,
column-gap: 1.5rem; column-gap: 1.5rem;
row-gap: 0.9rem; row-gap: 0.9rem;
align-items: center; align-items: center;
padding-left: 1rem;
padding-right: 1rem;
} }
.desktop-header-main { .desktop-header-main {
@@ -279,6 +327,7 @@ h3,
grid-column: 2; grid-column: 2;
grid-row: 1; grid-row: 1;
display: flex; display: flex;
gap: 0.3rem;
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
@@ -309,6 +358,10 @@ h3,
.desktop-actions > * { .desktop-actions > * {
white-space: nowrap; white-space: nowrap;
} }
.desktop-nav a {
padding: 0.5rem 0.74rem;
}
} }
.user-chip, .user-chip,
@@ -396,6 +449,14 @@ h3,
linear-gradient(180deg, color-mix(in srgb, var(--surface) 86%, #fff 14%), color-mix(in srgb, var(--surface) 80%, #ffe5d2 20%)); linear-gradient(180deg, color-mix(in srgb, var(--surface) 86%, #fff 14%), color-mix(in srgb, var(--surface) 80%, #ffe5d2 20%));
} }
[data-theme="dark"] .hero {
background:
linear-gradient(135deg, rgba(255, 255, 255, 0.06), transparent 42%),
linear-gradient(180deg, rgba(64, 55, 52, 0.98), rgba(49, 42, 39, 0.99));
border-color: rgba(243, 177, 125, 0.14);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.24);
}
.hero h1, .hero h1,
.page-intro h1, .page-intro h1,
.panel h2 { .panel h2 {
@@ -614,6 +675,11 @@ h3 {
background: var(--sky-soft); background: var(--sky-soft);
} }
[data-theme="dark"] .status-idea {
background: rgba(126, 143, 160, 0.24);
color: #ece8e4;
}
.status-soft { .status-soft {
background: var(--lilac-soft); background: var(--lilac-soft);
} }
@@ -702,6 +768,10 @@ h3 {
gap: 1rem; gap: 1rem;
} }
.dashboard-spaced-panel > .panel-head + * {
margin-top: 0.45rem;
}
.template-library-grid { .template-library-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
@@ -1078,6 +1148,14 @@ legend {
background: color-mix(in srgb, var(--surface-strong) 84%, #fff 16%); background: color-mix(in srgb, var(--surface-strong) 84%, #fff 16%);
} }
[data-theme="dark"] .template-card,
[data-theme="dark"] .template-list-card,
[data-theme="dark"] .suggestion-card {
background: linear-gradient(180deg, rgba(66, 57, 54, 0.98), rgba(54, 47, 44, 0.99));
border-color: rgba(243, 177, 125, 0.12);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
}
.selected-quick-action { .selected-quick-action {
background: linear-gradient(180deg, color-mix(in srgb, var(--accent-soft) 82%, #fff 18%), color-mix(in srgb, var(--surface-strong) 82%, #fff 18%)); background: linear-gradient(180deg, color-mix(in srgb, var(--accent-soft) 82%, #fff 18%), color-mix(in srgb, var(--surface-strong) 82%, #fff 18%));
border-color: color-mix(in srgb, var(--accent) 36%, var(--line) 64%); border-color: color-mix(in srgb, var(--accent) 36%, var(--line) 64%);
@@ -1128,6 +1206,12 @@ legend {
border: 1px solid var(--line); border: 1px solid var(--line);
} }
[data-theme="dark"] .hint-chip {
background: linear-gradient(180deg, rgba(77, 68, 64, 0.96), rgba(63, 56, 53, 0.98));
border-color: rgba(243, 177, 125, 0.12);
color: #f0e8e2;
}
.suggestion-row { .suggestion-row {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
@@ -1367,6 +1451,20 @@ legend {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.week-slot-title {
display: inline-flex;
align-items: center;
gap: 0.5rem;
min-width: 0;
}
.week-slot-title .ui-icon {
width: 1rem;
height: 1rem;
color: var(--accent-strong);
flex: 0 0 auto;
}
.week-slot-head-meta { .week-slot-head-meta {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -1607,6 +1705,11 @@ legend {
min-width: 5rem; min-width: 5rem;
} }
.theme-toggle,
.mobile-extra-button[data-theme-toggle] {
gap: 0.55rem;
}
.ui-icon { .ui-icon {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
@@ -1651,6 +1754,36 @@ legend {
mask-image: url("../icons/fa/calendar-days.svg"); mask-image: url("../icons/fa/calendar-days.svg");
} }
.icon-daypart-breakfast {
-webkit-mask-image: url("../icons/dayparts/breakfast.svg");
mask-image: url("../icons/dayparts/breakfast.svg");
}
.icon-daypart-morning-snack {
-webkit-mask-image: url("../icons/dayparts/morning-snack.svg");
mask-image: url("../icons/dayparts/morning-snack.svg");
}
.icon-daypart-lunch {
-webkit-mask-image: url("../icons/dayparts/lunch.svg");
mask-image: url("../icons/dayparts/lunch.svg");
}
.icon-daypart-afternoon-snack {
-webkit-mask-image: url("../icons/dayparts/afternoon-snack.svg");
mask-image: url("../icons/dayparts/afternoon-snack.svg");
}
.icon-daypart-dinner {
-webkit-mask-image: url("../icons/dayparts/dinner.svg");
mask-image: url("../icons/dayparts/dinner.svg");
}
.icon-daypart-late-snack {
-webkit-mask-image: url("../icons/dayparts/late-snack.svg");
mask-image: url("../icons/dayparts/late-snack.svg");
}
.icon-archive { .icon-archive {
-webkit-mask-image: url("../icons/fa/archive.svg"); -webkit-mask-image: url("../icons/fa/archive.svg");
mask-image: url("../icons/fa/archive.svg"); mask-image: url("../icons/fa/archive.svg");
@@ -1696,6 +1829,16 @@ legend {
mask-image: url("../icons/fa/mobile-screen-button.svg"); mask-image: url("../icons/fa/mobile-screen-button.svg");
} }
.icon-sun-theme {
-webkit-mask-image: url("../icons/fa/theme-sun.svg");
mask-image: url("../icons/fa/theme-sun.svg");
}
.icon-moon-theme {
-webkit-mask-image: url("../icons/fa/theme-moon.svg");
mask-image: url("../icons/fa/theme-moon.svg");
}
.icon-apple-whole { .icon-apple-whole {
-webkit-mask-image: url("../icons/fa/apple-whole.svg"); -webkit-mask-image: url("../icons/fa/apple-whole.svg");
mask-image: url("../icons/fa/apple-whole.svg"); mask-image: url("../icons/fa/apple-whole.svg");
@@ -2005,6 +2148,10 @@ legend {
.mobile-nav-button { .mobile-nav-button {
cursor: pointer; cursor: pointer;
font: inherit; font: inherit;
background: transparent;
color: var(--muted);
border: 0;
box-shadow: none;
} }
.mobile-bottom-nav a.active, .mobile-bottom-nav a.active,
@@ -2012,6 +2159,52 @@ legend {
.mobile-nav-button.is-open { .mobile-nav-button.is-open {
background: var(--accent-soft); background: var(--accent-soft);
color: var(--text); color: var(--text);
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-button.is-open {
background: var(--accent-soft);
color: var(--text);
border: 0;
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-stack .mobile-nav-button {
background: transparent;
color: var(--muted);
border: 0;
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-stack .mobile-nav-button.is-open {
background: var(--accent-soft);
color: var(--text);
border: 0;
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-extension .mobile-extra-button,
[data-theme="dark"] .mobile-nav-extension .mobile-extra-form .mobile-extra-button {
background: transparent;
color: var(--muted);
border: 0;
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-extension .mobile-extra-button[data-theme-toggle] {
background: transparent;
color: var(--muted);
border: 0;
box-shadow: none;
}
[data-theme="dark"] .mobile-nav-extension .mobile-extra-button:hover,
[data-theme="dark"] .mobile-nav-extension .mobile-extra-button:focus-visible,
[data-theme="dark"] .mobile-nav-extension .mobile-extra-form .mobile-extra-button:hover,
[data-theme="dark"] .mobile-nav-extension .mobile-extra-form .mobile-extra-button:focus-visible {
background: var(--accent-soft);
color: var(--text);
box-shadow: none;
} }
.mobile-profile-link { .mobile-profile-link {
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M32.7 224.4l24.2 138.1 100.3 97.4 138 19.5 123.1-65.8 61.1-126-24.2-138.1-100.3-97.4-138-19.5-123.1 65.8-61.1 126zM208 336a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm32-160a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zM400 304a32 32 0 1 1 -64 0 32 32 0 1 1 64 0z"/><path fill="currentColor" d="M93.8 98.4l-61.1 126 24.2 138.1 100.3 97.4 138 19.5 123.1-65.8 61.1-126-24.2-138.1-100.3-97.4-138-19.5-123.1 65.8zM213.9 16L362.2 37 470 141.6 496 289.9 430.3 425.3 298.1 496 149.8 475 42 370.4 16 222.1 81.7 86.7 213.9 16zM208 144a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm16 32a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zM144 336a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm192-80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm16 32a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M80 208l352 0 0 288-352 0 0-288z"/><path fill="currentColor" d="M160 0l0 8c0 23.9 16.8 39.5 37.4 58.1l1 .9c19.2 17.3 41.6 37.5 41.6 69l0 8-16 0 0-8c0-23.9-16.8-39.5-37.4-58.1l-1-.9C166.4 59.8 144 39.6 144 8l0-8 16 0zM80 208l0 288 352 0 0-288-352 0zm368 0l0 176 24 0c48.6 0 88-39.4 88-88s-39.4-88-88-88l-24 0zm0 192l0 112-384 0 0-320 408 0c57.4 0 104 46.6 104 104S529.4 400 472 400l-24 0zM272 8c0 23.9 16.8 39.5 37.4 58.1l1 .9c19.2 17.3 41.6 37.5 41.6 69l0 8-16 0 0-8c0-23.9-16.8-39.5-37.4-58.1l-1-.9C278.4 59.8 256 39.6 256 8l0-8 16 0 0 8z"/></svg>

After

Width:  |  Height:  |  Size: 820 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M16 16l0 168c0 13.3 10.7 24 24 24l24 0 0-192-48 0zm64 0l0 192 24 0c13.3 0 24-10.7 24-24l0-168-48 0zm32 239.6l0 86.8c1.1 2.9 2.3 5.8 3.6 8.7 5.5-.9 10.7-2.4 15.6-4.4 34.8 78.5 113.4 133.3 204.9 133.3 89.4 0 166.5-52.3 202.4-128l-58.4 0 0-192c0-28.6 5.6-52.9 14.5-73.5-4.6-4.3-9.5-8.5-14.5-12.5l0 10.3c-38.9-32.7-89.2-52.4-144-52.4-62.7 0-119.3 25.7-160 67.2 0-25.4 0 2.9 0 84.8 0 37.1-28 67.6-64 71.6zm368 .4a144 144 0 1 1 -288 0 144 144 0 1 1 288 0zm-272 0a128 128 0 1 0 256 0 128 128 0 1 0 -256 0zm320-96l0 144 96 0 0-265.6c-11 4.5-25 11.2-38.9 20.8-29.5 20.3-57.1 52-57.1 100.8z"/><path fill="currentColor" d="M480 64l0 20.4C441.1 51.7 390.8 32 336 32 273.3 32 216.7 57.7 176 99.2l0-22.1c42.5-38 98.5-61.1 160-61.1 54 0 103.9 17.9 144 48zm32 96c0-87.2 77.7-125.9 112-138.8 9.7-3.6 16-5.2 16-5.2l0 480-16 0 0-176-112 0 0-160zM128 16l16 0 0 168c0 22.1-17.9 40-40 40l-24 0 0 272-16 0 0-272-24 0c-22.1 0-40-17.9-40-40l0-168 16 0 0 168c0 13.3 10.7 24 24 24l24 0 0-192 16 0 0 192 24 0c13.3 0 24-10.7 24-24l0-168zM556 352c-37 84.8-121.6 144-220 144-98.8 0-183.6-59.7-220.4-144.9 5.4-.9 10.6-2.4 15.6-4.4 34.8 78.5 113.4 133.3 204.9 133.3 89.4 0 166.5-52.3 202.4-128l17.6 0zM336 400a144 144 0 1 1 0-288 144 144 0 1 1 0 288zm0-16a128 128 0 1 0 0-256 128 128 0 1 0 0 256zm288-80l0-265.6c-11 4.5-25 11.2-38.9 20.8-29.5 20.3-57.1 52-57.1 100.8l0 144 96 0z"/></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 576"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M99.1 99.8c36.8-31.2 88.7-50.7 158.9-51.8 70.8 1.3 118.7 27.7 149.8 67.9 32.6 42.2 48.7 102.3 48.7 172s-16.1 129.8-48.7 172c-31 40.2-79 66.6-149.8 67.9-70.2-1.1-122.1-20.6-158.9-51.8 14.2 2.5 29.3 3.8 45.4 3.8 4.1 0 8.1-.1 12-.2l0 .2c80.4 0 138.3-19.7 176.2-55.9 38-36.3 51.8-85.6 51.8-136.1s-13.8-99.8-51.8-136.1C294.8 115.7 236.9 96 156.5 96l0 .2c-3.9-.2-7.9-.2-12-.2-16.1 0-31.2 1.3-45.4 3.8zM252.5 .2C125.1 3.6 42.8 62.2 3.5 150.3l38.2 27.5c21.9-20.1 54.9-33.8 102.8-33.8 53.4 0 88.4 16.9 110.2 41.2 22.3 24.8 33.8 60.5 33.8 102.8S277 366 254.7 390.8c-21.9 24.4-56.8 41.2-110.2 41.2-47.9 0-80.9-13.6-102.8-33.8L3.5 425.7c39.3 88.2 121.6 146.7 249 150.1l0 .2c1.9 0 3.8 0 5.6 0 2.1 0 4.2 0 6.4 0 97.8 0 170.8-31.5 219.2-85.3 47.9-53.4 68.8-125.7 68.8-202.7S531.6 138.7 483.6 85.3c-48.3-53.8-121.4-85.3-219.2-85.3-2.1 0-4.3 0-6.4 0-1.9 0-3.7 0-5.6 0l0 .2zM216.5 252c0-26.5-14.4-48-48-48s-48 21.5-48 48 14.4 48 48 48 48-21.5 48-48zm-144 96c25.2 0 36-16.1 36-36s-10.8-36-36-36-36 16.1-36 36 10.8 36 36 36z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M16 80l0 96 480 0 0-96-480 0zm0 256l0 96 480 0 0-96-101.6 0-70 46.7-4.4 3-4.4-3-70-46.7-229.6 0z"/><path fill="currentColor" d="M496 80l0 96-480 0 0-96 480 0zM16 64l-16 0 0 128 512 0 0-128-496 0zM0 320l0 128 512 0 0-128-122.4 0-2 1.3-67.6 45-67.6-45-2-1.3-250.4 0zm16 16l229.6 0 70 46.7 4.4 3 4.4-3 70-46.7 101.6 0 0 96-480 0 0-96zM130.8 224.5l-3-1.1-3 1.3-112 48-7.4 3.2 6.3 14.7 7.4-3.2 109-46.7 125 46.9 2.8 1.1 2.8-1.1 125-46.9 109 46.7 7.4 3.2 6.3-14.7-7.4-3.2-112-48-3-1.3-3 1.1-125.2 46.9-125.2-46.9z"/></svg>

After

Width:  |  Height:  |  Size: 788 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path opacity=".4" fill="currentColor" d="M16 288c0 60.7 19 113.3 46.8 150.4 27.5 36.6 62.4 56.8 95.3 57.6l62-15.5 3.9-1 3.9 1 62 15.5c32.9-.7 67.8-20.9 95.3-57.6 27.8-37.1 46.8-89.7 46.8-150.4 0-36-8.5-72.9-25.1-100.3-16-26.3-38.6-42.9-68.8-43.7l-109.8 31.4-4.4 1.3-4.4-1.3-109.8-31.4C79.7 144.8 57 161.4 41.1 187.7 24.5 215.1 16 252 16 288zM224 80l0 16 16 0c35.3 0 64-28.7 64-64l0-16-16 0c-35.3 0-64 28.7-64 64z"/><path fill="currentColor" d="M240 96c35.3 0 64-28.7 64-64l0-16-16 0c-35.3 0-64 28.7-64 64l0 16 16 0zm-32 16l0-32c0-44.2 35.8-80 80-80l32 0 0 32c0 44.2-35.8 80-80 80l-32 0zm-96 16l112 32 112-32c76.3 0 112 83.7 112 160 0 128-80 224-160 224l-64-16-64 16C80 512 0 416 0 288 0 211.7 35.7 128 112 128zm116.4 47.4l-4.4 1.3-4.4-1.3-109.8-31.4C79.7 144.8 57 161.4 41.1 187.7 24.5 215.1 16 252 16 288 16 348.7 35 401.3 62.8 438.4 90.3 475 125.2 495.2 158.1 496l62-15.5 3.9-1 3.9 1 62 15.5c32.9-.7 67.8-20.9 95.3-57.6 27.8-37.1 46.8-89.7 46.8-150.4 0-36-8.5-72.9-25.1-100.3-16-26.3-38.6-42.9-68.8-43.7L228.4 175.4z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 576"><path fill="currentColor" d="M99.1 99.8c36.8-31.2 88.7-50.7 158.9-51.8 70.8 1.3 118.7 27.7 149.8 67.9 32.6 42.2 48.7 102.3 48.7 172s-16.1 129.8-48.7 172c-31 40.2-79 66.6-149.8 67.9-70.2-1.1-122.1-20.6-158.9-51.8 14.2 2.5 29.3 3.8 45.4 3.8 4.1 0 8.1-.1 12-.2l0 .2c80.4 0 138.3-19.7 176.2-55.9 38-36.3 51.8-85.6 51.8-136.1s-13.8-99.8-51.8-136.1C294.8 115.7 236.9 96 156.5 96l0 .2c-3.9-.2-7.9-.2-12-.2-16.1 0-31.2 1.3-45.4 3.8zM252.5 .2C125.1 3.6 42.8 62.2 3.5 150.3l38.2 27.5c21.9-20.1 54.9-33.8 102.8-33.8 53.4 0 88.4 16.9 110.2 41.2 22.3 24.8 33.8 60.5 33.8 102.8S277 366 254.7 390.8c-21.9 24.4-56.8 41.2-110.2 41.2-47.9 0-80.9-13.6-102.8-33.8L3.5 425.7c39.3 88.2 121.6 146.7 249 150.1l0 .2c1.9 0 3.8 0 5.6 0 2.1 0 4.2 0 6.4 0 97.8 0 170.8-31.5 219.2-85.3 47.9-53.4 68.8-125.7 68.8-202.7S531.6 138.7 483.6 85.3c-48.3-53.8-121.4-85.3-219.2-85.3-2.1 0-4.3 0-6.4 0-1.9 0-3.7 0-5.6 0l0 .2zM216.5 252c0-26.5-14.4-48-48-48s-48 21.5-48 48 14.4 48 48 48 48-21.5 48-48zm-144 96c25.2 0 36-16.1 36-36s-10.8-36-36-36-36 16.1-36 36 10.8 36 36 36z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 576"><path fill="currentColor" d="M309.6 0L266.4 0 222 47.9c-13.9 15-33.5 23.3-53.9 23L89.2 63 63 89.4 70.9 164.2c.3 19.5-7.3 38.3-21.1 52.1L0 266.1 0 309.6 47.9 354c15 13.9 23.3 33.5 23 53.9l-7.9 78.8 28 26 73.3-12.8c23.9-2.2 47.3 7.7 62.4 26.4l40.2 49.6 42.3 0 40.2-49.6c15.1-18.7 38.5-28.5 62.4-26.4l73.3 12.8 28-26-7.9-78.8c-.3-20.4 8-40 23-53.9l47.9-44.4 0-43.5-49.8-49.8c-13.8-13.8-21.4-32.6-21.1-52.1l7.9-74.8-26.3-26.4-78.8 7.9c-20.4 .3-40-8-53.9-23L309.6 0zM288 64.4l4.8 9.4c26.8 52.1 87.4 77.2 143.2 59.3l10-3.2-3.2 10c-17.9 55.8 7.2 116.4 59.3 143.2l9.4 4.8-9.4 4.8c-52.1 26.8-77.2 87.4-59.3 143.2l3.2 10-10-3.2c-55.8-17.9-116.4 7.2-143.2 59.3l-4.8 9.4-4.8-9.4c-26.8-52.1-87.4-77.2-143.2-59.3l-10 3.2 3.2-10c17.9-55.8-7.2-116.4-59.3-143.2l-9.4-4.8 9.4-4.8c52.1-26.8 77.2-87.4 59.3-143.2l-3.2-10 10 3.2c55.8 17.9 116.4-7.2 143.2-59.3l4.8-9.4zM322.3 224c8.6 14.4 13.7 36.5 13.7 64s-5.1 49.6-13.7 64c-7.8 13.1-18.4 20-34.3 20s-26.5-6.9-34.3-20c-8.6-14.4-13.7-36.5-13.7-64s5.1-49.6 13.7-64c7.8-13.1 18.4-20 34.3-20s26.5 6.9 34.3 20zM288 156c-43.2 0-77.2 14-100.2 39.6-22.6 25.1-31.8 58.5-31.8 92.4s9.2 67.3 31.8 92.4c23 25.6 57 39.6 100.2 39.6s77.2-14 100.2-39.6C410.8 355.3 420 321.9 420 288s-9.2-67.3-31.8-92.4C365.2 170 331.2 156 288 156z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+16 -1
View File
@@ -12,7 +12,22 @@
root.dataset.theme = finalTheme; root.dataset.theme = finalTheme;
toggles().forEach((button) => { toggles().forEach((button) => {
button.textContent = finalTheme === "dark" ? "Hell" : "Dunkel"; const nextModeLabel = finalTheme === "dark" ? "Hell" : "Dunkel";
const label = button.querySelector("[data-theme-label]");
const icon = button.querySelector("[data-theme-icon]");
if (label) {
label.textContent = nextModeLabel;
} else {
button.textContent = nextModeLabel;
}
if (icon) {
icon.classList.toggle("icon-sun-theme", finalTheme === "dark");
icon.classList.toggle("icon-moon-theme", finalTheme !== "dark");
}
button.setAttribute("aria-label", `${nextModeLabel} aktivieren`);
}); });
}; };
+7 -4
View File
@@ -53,7 +53,10 @@
{% if g.user %} {% if g.user %}
<div class="desktop-header-sub"> <div class="desktop-header-sub">
<div class="header-actions desktop-actions"> <div class="header-actions desktop-actions">
<button class="theme-toggle ghost-button" type="button" data-theme-toggle>Hell</button> <button class="theme-toggle ghost-button" type="button" data-theme-toggle aria-label="Darstellung wechseln">
<span class="ui-icon icon-sun-theme" data-theme-icon></span>
<span data-theme-label>Hell</span>
</button>
<a class="ghost-button" href="{{ url_for('main.settings_view') }}">Optionen</a> <a class="ghost-button" href="{{ url_for('main.settings_view') }}">Optionen</a>
<a class="user-chip" href="{{ url_for('auth.profile') }}"> <a class="user-chip" href="{{ url_for('auth.profile') }}">
<span class="user-chip-title">{{ g.user.display_name or g.user.username }}</span> <span class="user-chip-title">{{ g.user.display_name or g.user.username }}</span>
@@ -114,9 +117,9 @@
<a class="mobile-extra-link" href="{{ url_for('admin.user_list') }}"><span class="ui-icon icon-sparkles"></span><span>Nutzer</span></a> <a class="mobile-extra-link" href="{{ url_for('admin.user_list') }}"><span class="ui-icon icon-sparkles"></span><span>Nutzer</span></a>
<a class="mobile-extra-link" href="{{ url_for('admin.category_settings') }}"><span class="ui-icon icon-seedling"></span><span>Kategorien</span></a> <a class="mobile-extra-link" href="{{ url_for('admin.category_settings') }}"><span class="ui-icon icon-seedling"></span><span>Kategorien</span></a>
{% endif %} {% endif %}
<button class="mobile-extra-link mobile-extra-button" type="button" data-theme-toggle> <button class="mobile-extra-link mobile-extra-button" type="button" data-theme-toggle aria-label="Darstellung wechseln">
<span class="ui-icon icon-mobile-screen-button"></span> <span class="ui-icon icon-sun-theme" data-theme-icon></span>
<span>Modus</span> <span data-theme-label>Hell</span>
</button> </button>
<form method="post" action="{{ url_for('auth.logout') }}" class="mobile-extra-form"> <form method="post" action="{{ url_for('auth.logout') }}" class="mobile-extra-form">
{{ csrf_input() }} {{ csrf_input() }}
+2 -2
View File
@@ -91,7 +91,7 @@
{% endif %} {% endif %}
</article> </article>
<article class="panel"> <article class="panel dashboard-spaced-panel">
<div class="panel-head"> <div class="panel-head">
<h2>Kurz griffbereit</h2> <h2>Kurz griffbereit</h2>
<a href="{{ url_for('main.home_view') }}">Alles unter Zuhause</a> <a href="{{ url_for('main.home_view') }}">Alles unter Zuhause</a>
@@ -122,7 +122,7 @@
</section> </section>
<section class="two-column"> <section class="two-column">
<article class="panel"> <article class="panel dashboard-spaced-panel">
<div class="panel-head"> <div class="panel-head">
<h2>Was zuhause gut zusammenpasst</h2> <h2>Was zuhause gut zusammenpasst</h2>
<a href="{{ url_for('main.home_view') }}">Zuhause öffnen</a> <a href="{{ url_for('main.home_view') }}">Zuhause öffnen</a>
+1 -1
View File
@@ -84,7 +84,7 @@
> >
<summary class="day-tile-summary"> <summary class="day-tile-summary">
<div class="day-tile-summary-main"> <div class="day-tile-summary-main">
<div class="day-tile-icon"><span class="ui-icon icon-calendar"></span></div> <div class="day-tile-icon"><span class="ui-icon {{ daypart_icon_class(section.daypart.slug) }}"></span></div>
<div> <div>
<h2>{{ section.daypart.name }}</h2> <h2>{{ section.daypart.name }}</h2>
{% if section.summary_items %} {% if section.summary_items %}
+4 -1
View File
@@ -129,7 +129,10 @@
{% if slot.is_snack_daypart and not slot.visible_by_default %}hidden data-week-snack-slot{% endif %} {% if slot.is_snack_daypart and not slot.visible_by_default %}hidden data-week-snack-slot{% endif %}
> >
<div class="week-slot-head"> <div class="week-slot-head">
<strong>{{ slot.daypart.name }}</strong> <div class="week-slot-title">
<span class="ui-icon {{ daypart_icon_class(slot.daypart.slug) }}"></span>
<strong>{{ slot.daypart.name }}</strong>
</div>
<div class="week-slot-head-meta"> <div class="week-slot-head-meta">
<span class="week-slot-count{% if slot.entries %} status-home{% endif %}">{{ slot.entries|length }}</span> <span class="week-slot-count{% if slot.entries %} status-home{% endif %}">{{ slot.entries|length }}</span>
<button class="week-slot-add" type="button" data-week-slot-picker-open aria-label="{{ slot.daypart.name }} an {{ weekday_name(card.date) }} direkt ergänzen">+</button> <button class="week-slot-add" type="button" data-week-slot-picker-open aria-label="{{ slot.daypart.name }} an {{ weekday_name(card.date) }} direkt ergänzen">+</button>