fix: Navigation bricht auf schmalen Bildschirmen um, gewähltes Tortensegment oben, Legendenzusatz nicht fett (A14-T6)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 13:16:57 +02:00
co-authored by Claude Haiku 4.5
parent 94fd7ab96e
commit dfb814955f
3 changed files with 38 additions and 1 deletions
+3
View File
@@ -12,6 +12,8 @@ body {
nav { nav {
display: flex; display: flex;
gap: 1rem; gap: 1rem;
flex-wrap: wrap;
row-gap: 0.4rem;
align-items: center; align-items: center;
border-bottom: 1px solid #ccc; border-bottom: 1px solid #ccc;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
@@ -278,4 +280,5 @@ label:has(input:disabled), label:has(select:disabled) {
.torte-svg .seg.klickbar:hover { opacity: 0.85; } .torte-svg .seg.klickbar:hover { opacity: 0.85; }
.torte-svg .seg.gewaehlt { stroke: #222; stroke-width: 0.05; } .torte-svg .seg.gewaehlt { stroke: #222; stroke-width: 0.05; }
.legende li.gewaehlt { font-weight: bold; } .legende li.gewaehlt { font-weight: bold; }
.legende-zusatz { font-weight: normal; color: #666; }
#aufteilung-kategorie h2 { font-size: 1.1rem; margin-top: 1.5rem; } #aufteilung-kategorie h2 { font-size: 1.1rem; margin-top: 1.5rem; }
+3 -1
View File
@@ -13,7 +13,9 @@ class="seg {{ seg.s.color }}{% if seg.q %} klickbar{% endif %}{% if seg.gewaehlt
<figure class="torte"> <figure class="torte">
<figcaption>{{ titel }}</figcaption> <figcaption>{{ titel }}</figcaption>
<svg class="torte-svg" viewBox="-1.05 -1.05 2.1 2.1" role="img" aria-label="{{ titel }}"> <svg class="torte-svg" viewBox="-1.05 -1.05 2.1 2.1" role="img" aria-label="{{ titel }}">
{% for seg in segmente %}{% set s = seg.s %} {# Gewähltes Segment zuletzt zeichnen, damit sein Umriss nicht von
Nachbarsegmenten überdeckt wird (A14). #}
{% for seg in (segmente|rejectattr('gewaehlt')|list) + (segmente|selectattr('gewaehlt')|list) %}{% set s = seg.s %}
{% if s.path %}<path d="{{ s.path }}" {{ seg_attrs(seg) }}><title>{{ s.label }}{% if s.merged %} ({{ s.members|join(', ') }}){% endif %}: {{ s.value|eur }} € ({{ s.share|pct }})</title></path> {% if s.path %}<path d="{{ s.path }}" {{ seg_attrs(seg) }}><title>{{ s.label }}{% if s.merged %} ({{ s.members|join(', ') }}){% endif %}: {{ s.value|eur }} € ({{ s.share|pct }})</title></path>
{% else %}<circle r="1" {{ seg_attrs(seg) }}><title>{{ s.label }}{% if s.merged %} ({{ s.members|join(', ') }}){% endif %}: {{ s.value|eur }} € ({{ s.share|pct }})</title></circle>{% endif %} {% else %}<circle r="1" {{ seg_attrs(seg) }}><title>{{ s.label }}{% if s.merged %} ({{ s.members|join(', ') }}){% endif %}: {{ s.value|eur }} € ({{ s.share|pct }})</title></circle>{% endif %}
{% endfor %} {% endfor %}
+32
View File
@@ -1,6 +1,8 @@
import re import re
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from pathlib import Path
from types import SimpleNamespace
from app.engine.loans import add_months from app.engine.loans import add_months
from app.models.tables import (Category, Loan, RecurringItem, Scenario, from app.models.tables import (Category, Loan, RecurringItem, Scenario,
@@ -310,3 +312,33 @@ def test_uebrige_mitglieder_in_legende_der_zweiten_torte(client, db):
legende = re.search(r'<ul class="legende">(.*?)</ul>', t, re.S).group(1) legende = re.search(r'<ul class="legende">(.*?)</ul>', t, re.S).group(1)
assert 'class="legende-zusatz"' in legende assert 'class="legende-zusatz"' in legende
assert "Kleinposten 3" in legende assert "Kleinposten 3" in legende
CSS = (Path(__file__).resolve().parent.parent / "app" / "static" / "style.css").read_text()
def test_nav_bricht_um():
nav = re.search(r"(?m)^nav\s*\{([^}]*)\}", CSS).group(1)
assert re.search(r"flex-wrap:\s*wrap", nav)
def test_legende_zusatz_nicht_fett_und_figcaption_bleibt_fett():
assert re.search(r"\.legende-zusatz\s*\{[^}]*font-weight:\s*normal", CSS)
# Nutzerwunsch A14: Bildunterschrift der Torte bleibt fett.
assert re.search(r"\.torte figcaption\s*\{[^}]*font-weight:\s*bold", CSS)
def test_gewaehltes_segment_zuletzt_gezeichnet():
from app.routers.gui import templates
def seg(label, gewaehlt):
s = SimpleNamespace(path=f"M0 0 L{label}", color="s1", label=label, merged=False, members=[],
value=Decimal("1.00"), share=Decimal("50.0"))
return {"s": s, "q": None, "gewaehlt": gewaehlt, "zusatz": None}
torte = templates.env.get_template("_torte_macros.html").module.torte
html = str(torte([seg("Alpha", True), seg("Beta", False)], "Titel"))
svg = html.split("<svg", 1)[1].split("</svg>", 1)[0]
assert svg.index("M0 0 LBeta") < svg.index("M0 0 LAlpha")
legende = html.split('<ul class="legende">', 1)[1]
assert legende.index("Alpha") < legende.index("Beta") # Legende behält Reihenfolge