diff --git a/backend/static/css/components.css b/backend/static/css/components.css index afdcb80..750fc4a 100644 --- a/backend/static/css/components.css +++ b/backend/static/css/components.css @@ -441,6 +441,7 @@ textarea.form-control { padding: var(--space-4); backdrop-filter: blur(2px); animation: overlay-in var(--transition-normal) ease; + touch-action: manipulation; } @media (min-width: 768px) { .modal-overlay { align-items: center; } @@ -812,3 +813,409 @@ textarea.form-control { /* Leaflet-Attribution ausblenden */ .leaflet-control-attribution { display: none !important; } + +/* ============================================================ + GESUNDHEIT + ============================================================ */ + +/* Header mit KI-Button */ +.health-header { + display: flex; + justify-content: flex-end; + padding: var(--space-3) 0 var(--space-2); +} + +/* Tab-Leiste — Mobile: horizontal scrollbar, Desktop: umbrechen */ +.health-tabs { + display: flex; + flex-wrap: wrap; + gap: var(--space-1) var(--space-1); + padding-bottom: var(--space-2); + margin-bottom: var(--space-3); +} +/* Auf sehr kleinen Screens: scrollen statt umbrechen */ +@media (max-width: 480px) { + .health-tabs { + flex-wrap: nowrap; + overflow-x: auto; + padding-right: var(--space-4); + scrollbar-width: none; + } + .health-tabs::-webkit-scrollbar { display: none; } +} + +.health-tab { + flex-shrink: 0; + padding: var(--space-2) var(--space-3); + border: 2px solid var(--c-border); + border-radius: var(--radius-full); + background: var(--c-surface); + color: var(--c-text-secondary); + font-size: var(--text-sm); + font-weight: var(--weight-medium); + cursor: pointer; + white-space: nowrap; + transition: all var(--transition-fast); + touch-action: manipulation; +} +.health-tab.active { + background: var(--c-primary); + border-color: var(--c-primary); + color: var(--c-text-inverse); +} + +/* Karten-Liste */ +.health-list { + display: flex; + flex-direction: column; + gap: var(--space-3); +} + +/* Einzelne Karte */ +.health-card { + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius-md); + padding: var(--space-4); + cursor: pointer; + display: flex; + gap: var(--space-3); + align-items: flex-start; + transition: box-shadow var(--transition-fast), transform var(--transition-fast); +} +.health-card:active { transform: scale(0.985); } +.health-card--inactive { opacity: 0.55; } + +.health-card-body { flex: 1; min-width: 0; } +.health-card-title { font-weight: var(--weight-semibold); margin-bottom: var(--space-1); } +.health-card-meta { font-size: var(--text-sm); color: var(--c-text-secondary); } +.health-card-next { font-size: var(--text-sm); font-weight: var(--weight-medium); margin-top: var(--space-1); } +.health-card-note { font-size: var(--text-sm); color: var(--c-text-secondary); margin-top: var(--space-1); } + +/* Ampel-Punkt (links an der Karte) */ +.health-card-ampel { + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; + margin-top: 5px; +} +.ampel-green { background: #22c55e; } +.ampel-yellow { background: #f59e0b; } +.ampel-red { background: #ef4444; } +.ampel-grey { background: var(--c-border); } + +.ampel-text-green { color: #16a34a; } +.ampel-text-yellow { color: #d97706; } +.ampel-text-red { color: #dc2626; } + +/* Gruppen-Label (z.B. "Aktuelle Medikamente") */ +.health-group-label { + font-size: var(--text-sm); + font-weight: var(--weight-semibold); + color: var(--c-text-secondary); + text-transform: uppercase; + letter-spacing: 0.05em; + padding: var(--space-3) 0 var(--space-1); +} + +/* Gewicht-Diagramm-Wrapper */ +.health-chart-wrap { + background: var(--c-surface); + border: 1px solid var(--c-border); + border-radius: var(--radius-md); + padding: var(--space-4); + margin-bottom: var(--space-4); + overflow: hidden; +} + +/* Dokument-Thumbnail und Icon */ +.health-doc-thumb { + width: 56px; + height: 56px; + object-fit: cover; + border-radius: var(--radius-sm); + flex-shrink: 0; +} +.health-doc-icon { + width: 56px; + height: 56px; + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; + background: var(--c-surface-2); + border-radius: var(--radius-sm); + flex-shrink: 0; +} + +/* Detail-Dialog DL */ +.health-detail-dl { + display: grid; + grid-template-columns: auto 1fr; + gap: var(--space-1) var(--space-4); + font-size: var(--text-sm); +} +.health-detail-dl dt { + color: var(--c-text-secondary); + font-weight: var(--weight-medium); + white-space: nowrap; +} +.health-detail-dl dd { margin: 0; } + +/* ------------------------------------------------------------ + DOG SWITCHER + Avatar-Leiste in Header (Mobile) + Sidebar-Logo (Desktop) + ------------------------------------------------------------ */ + +/* Aktiver (linker) Hund — primärer Ring */ +.dog-sw-active { + width: 34px; + height: 34px; + border-radius: var(--radius-full); + overflow: hidden; + background: var(--c-surface-2); + flex-shrink: 0; + cursor: pointer; + border: 2.5px solid var(--c-primary); + transition: transform var(--transition-fast), + box-shadow var(--transition-fast); +} +.dog-sw-active:hover { + transform: scale(1.06); + box-shadow: 0 0 0 3px var(--c-primary-subtle); +} +.dog-sw-active img { width:100%; height:100%; object-fit:cover; display:block; } +.dog-sw-active span { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 17px; +} + +/* "Ban Yaro" Label — füllt den Zwischenraum */ +.dog-sw-title { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* Gruppe der inaktiven Hunde (rechts) */ +.dog-sw-others { + display: flex; + align-items: center; + position: relative; /* Anker für Quickpicker-Dropdown */ + flex-shrink: 0; +} + +/* Inaktiver Hund-Avatar */ +.dog-sw-other { + width: 28px; + height: 28px; + border-radius: var(--radius-full); + overflow: hidden; + background: var(--c-surface-2); + border: 2px solid var(--c-surface); + cursor: pointer; + flex-shrink: 0; + transition: transform var(--transition-fast); + position: relative; +} +.dog-sw-other:hover { transform: scale(1.12); } +.dog-sw-other img { width:100%; height:100%; object-fit:cover; display:block; } +.dog-sw-other span { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 14px; +} + +/* Gestapelter Avatar-Stack (3+ Hunde) */ +.dog-sw-stack { + display: flex; + align-items: center; + cursor: pointer; +} +.dog-sw-stack .dog-sw-other { margin-left: -9px; } +.dog-sw-stack .dog-sw-other:first-child { margin-left: 0; } +.dog-sw-stack .dog-sw-other--0 { z-index: 3; } +.dog-sw-stack .dog-sw-other--1 { z-index: 2; } +.dog-sw-stack .dog-sw-other--2 { z-index: 1; } +.dog-sw-stack:hover .dog-sw-other { filter: brightness(1.05); } + +/* +N Überlauf-Badge */ +.dog-sw-more { + width: 28px; + height: 28px; + border-radius: var(--radius-full); + background: var(--c-surface-2); + border: 2px solid var(--c-surface); + display: flex; + align-items: center; + justify-content: center; + font-size: 9px; + font-weight: var(--weight-bold); + color: var(--c-text-secondary); + margin-left: -9px; + position: relative; + z-index: 0; +} + +/* Quickpicker-Dropdown */ +.dog-quickpick { + position: absolute; + top: calc(100% + 10px); + right: 0; + background: var(--c-surface); + border: 1px solid var(--c-border-light); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); + padding: var(--space-2); + min-width: 170px; + z-index: 600; +} +.dog-quickpick.hidden { display: none; } + +.dog-qp-item { + display: flex; + align-items: center; + gap: var(--space-3); + padding: var(--space-2) var(--space-3); + border-radius: var(--radius-md); + cursor: pointer; + font-size: var(--text-sm); + font-weight: var(--weight-medium); + color: var(--c-text); + transition: background var(--transition-fast); + -webkit-tap-highlight-color: transparent; +} +.dog-qp-item:hover { background: var(--c-bg); } + +.dog-qp-av { + width: 32px; + height: 32px; + border-radius: var(--radius-full); + overflow: hidden; + background: var(--c-surface-2); + flex-shrink: 0; +} +.dog-qp-av img { width:100%; height:100%; object-fit:cover; display:block; } +.dog-qp-av span { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 16px; +} + +/* Sidebar: größerer aktiver Avatar */ +#sidebar-dog-switcher .dog-sw-active { + width: 36px; + height: 36px; +} + +/* ------------------------------------------------------------ + DIARY — Multi-Dog (Hunde-Auswahl im Formular + Karten-Anzeige) + ------------------------------------------------------------ */ + +/* Avatar-Reihe in der Tagebuch-Karte */ +.diary-dog-row { + display: flex; + align-items: center; + gap: -4px; /* überlappend via margin */ + margin-top: var(--space-2); + flex-wrap: wrap; + gap: var(--space-1); +} + +.diary-dog-av { + width: 22px; + height: 22px; + border-radius: var(--radius-full); + overflow: hidden; + background: var(--c-surface-2); + border: 1.5px solid var(--c-surface); + flex-shrink: 0; +} +.diary-dog-av img { width:100%; height:100%; object-fit:cover; display:block; } +.diary-dog-av span { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + font-size: 12px; +} + +/* Hunde-Chip in der Detail-Ansicht */ +.diary-detail-dogs { + display: flex; + flex-wrap: wrap; + gap: var(--space-2); + margin-bottom: var(--space-3); +} + +.diary-dog-chip { + display: flex; + align-items: center; + gap: var(--space-1); + padding: 3px 8px 3px 4px; + background: var(--c-surface-2); + border-radius: var(--radius-full); + font-size: var(--text-xs); + font-weight: var(--weight-medium); + color: var(--c-text-secondary); +} +.diary-dog-chip .diary-dog-av { + width: 20px; + height: 20px; +} + +/* Hunde-Picker im Formular */ +.diary-dog-picker { + display: flex; + flex-wrap: wrap; + gap: var(--space-2); +} + +.diary-dog-pick-item { + display: flex; + align-items: center; + gap: var(--space-2); + padding: var(--space-2) var(--space-3); + border: 1.5px solid var(--c-border-light); + border-radius: var(--radius-full); + cursor: pointer; + font-size: var(--text-sm); + font-weight: var(--weight-medium); + color: var(--c-text-secondary); + transition: border-color var(--transition-fast), + background var(--transition-fast), + color var(--transition-fast); + -webkit-tap-highlight-color: transparent; + user-select: none; +} +.diary-dog-pick-item input { display: none; } + +.diary-dog-pick-item .diary-dog-av { + width: 26px; + height: 26px; +} + +.diary-dog-pick-item:hover { + border-color: var(--c-primary); + color: var(--c-text); +} + +.diary-dog-pick-item.checked { + border-color: var(--c-primary); + background: var(--c-primary-subtle); + color: var(--c-primary-dark); + font-weight: var(--weight-semibold); +} diff --git a/backend/static/css/layout.css b/backend/static/css/layout.css index 88fe171..2682530 100644 --- a/backend/static/css/layout.css +++ b/backend/static/css/layout.css @@ -58,6 +58,16 @@ flex: 1; } +/* Dog Switcher Container im Header */ +#header-dog-switcher { + flex: 1; + display: flex; + align-items: center; + gap: var(--space-2); + min-width: 0; + overflow: visible; +} + .header-back { display: flex; align-items: center; @@ -201,7 +211,7 @@ background: var(--c-surface); border-right: 1px solid var(--c-border-light); flex-direction: column; - overflow-y: auto; + overflow: hidden; /* Sidebar selbst scrollt nicht */ box-shadow: var(--shadow-sm); } @@ -229,14 +239,31 @@ color: var(--c-text); } -.sidebar-nav { - flex: 1; - padding: var(--space-4) var(--space-2); - display: flex; - flex-direction: column; - gap: var(--space-1); +.sidebar-add { + padding: var(--space-4) var(--space-4) var(--space-2); + flex-shrink: 0; } +.sidebar-nav { + flex: 1; + padding: var(--space-2) var(--space-2) var(--space-4); + display: flex; + flex-direction: column; + gap: var(--space-1); + overflow-y: auto; + min-height: 0; /* wichtig: flex-child darf kleiner werden als Inhalt */ + /* Firefox */ + scrollbar-width: thin; + scrollbar-color: var(--c-primary) var(--c-surface); +} +.sidebar-nav::-webkit-scrollbar { width: 6px; } +.sidebar-nav::-webkit-scrollbar-track { background: var(--c-surface); } +.sidebar-nav::-webkit-scrollbar-thumb { + background: var(--c-primary); + border-radius: 3px; +} +.sidebar-nav::-webkit-scrollbar-thumb:hover { background: var(--c-primary-dark); } + .sidebar-section-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); @@ -270,6 +297,12 @@ color: var(--c-primary-dark); font-weight: var(--weight-semibold); } +/* User-Eintrag bekommt nie den Active-Stil */ +.sidebar-item--user.active { + background: transparent; + color: var(--c-text-secondary); + font-weight: var(--weight-medium); +} .sidebar-item-icon { font-size: 18px; width: 24px; @@ -291,11 +324,7 @@ padding: 0 var(--space-1); } -.sidebar-footer { - padding: var(--space-4) var(--space-2); - border-top: 1px solid var(--c-border-light); - flex-shrink: 0; -} +/* sidebar-footer entfernt — Einstellungen/Konto sind jetzt Teil der scrollbaren Nav */ /* ------------------------------------------------------------ 5. PAGE WRAPPER (inneres Layout der Seiten) diff --git a/backend/static/icons/favicon-16.png b/backend/static/icons/favicon-16.png new file mode 100644 index 0000000..40b9c1f Binary files /dev/null and b/backend/static/icons/favicon-16.png differ diff --git a/backend/static/icons/favicon-32.png b/backend/static/icons/favicon-32.png new file mode 100644 index 0000000..7667efc Binary files /dev/null and b/backend/static/icons/favicon-32.png differ diff --git a/backend/static/icons/favicon.ico b/backend/static/icons/favicon.ico new file mode 100644 index 0000000..9c22a1c Binary files /dev/null and b/backend/static/icons/favicon.ico differ diff --git a/backend/static/icons/icon-180.png b/backend/static/icons/icon-180.png new file mode 100644 index 0000000..57a5fa6 Binary files /dev/null and b/backend/static/icons/icon-180.png differ diff --git a/backend/static/icons/icon-192.png b/backend/static/icons/icon-192.png new file mode 100644 index 0000000..2554fff Binary files /dev/null and b/backend/static/icons/icon-192.png differ diff --git a/backend/static/icons/icon-512.png b/backend/static/icons/icon-512.png new file mode 100644 index 0000000..58dc5fe Binary files /dev/null and b/backend/static/icons/icon-512.png differ diff --git a/backend/static/index.html b/backend/static/index.html index d5c5e22..f0fd842 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -6,9 +6,14 @@ + + + + + - + @@ -30,17 +35,23 @@
- Ban Yaro +
+ Ban Yaro +