- Gruppe: wählbares Emoji-Icon (groups.icon-Spalte + PUT /api/groups/{id});
wird in der Sidebar statt des Zahnrads angezeigt; Verwalten jetzt klares "⋯".
Gruppe umbenennen möglich (war vorher gesperrt).
- "Meine Kalender": der aktuell für Gruppen sichtbare Kalender wird mit 👥
gekennzeichnet.
- Gruppenansicht: Gruppenkalender-Termine zeigen, wer sie hinzugefügt hat
(👥 Vorname: Titel) und sind nach Ersteller eingefärbt; jeder kann weiterhin
Termine im Gruppenkalender anlegen. Version v34.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kombinierte Ansicht: kryptisches "[SC]"-Initialen-Präfix ersetzt durch den
Vornamen ("Guido: Titel") für fremde Termine; eigene Termine ohne Präfix;
Gruppen-Termine mit 👥. Zusätzlich feste Farbkodierung pro Besitzer, damit
jedes Mitglied als Gruppe lesbar ist. Version v33.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Profil: Anzeigename + Login-Name editierbar (vorher Benutzername read-only).
Login-Namenwechsel speichert den frisch zurueckgegebenen Token.
- Menue/Dropdown und "Erstellt von"/Picker zeigen den Anzeigenamen.
- localStorage-User um display_name ergaenzt. Version v32.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Plus-Icon (Kalender/Gruppen hinzufuegen): fehlerhafter SVG-Pfad (v11 statt
v6) -> korrekter, symmetrischer Plus-Pfad.
- Entfernen/Auge-Button per display:none statt opacity:0 -> reserviert keinen
Platz mehr; Kalendername nutzt volle Breite und kuerzt erst beim Hover
(wenn das Auge erscheint). Version v31.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim Ziehen wandert die Zeile jetzt live zwischen die anderen, die Liste
macht sichtbar Platz an der Zielposition. Container-dragover wird nur einmal
gebunden (kein Listener-Stacking pro Render). Version v30.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Quelle/Konto stand inline rechts und hat die Kalendernamen abgeschnitten.
Jetzt im title-Tooltip des Eintrags ("Name · Quelle"); der Name nutzt die
volle Breite. Version v29.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Sidebar: eine flache Kalenderliste statt Quellen-Gruppen; Quelle/Konto
klein-grau inline rechts neben dem Namen; per Drag&Drop sortierbar
(Reihenfolge pro Geraet in localStorage).
- Gruppenkalender serverseitig auch beim Besitzer als group:true markiert
-> erscheint nicht mehr in der "Fuer Gruppen sichtbar"-Auswahl und nicht
in der normalen Kalenderliste (nur unter Gruppen).
- Settings-URL-State: uiSettingsOpen wird beim Init aus der URL gesetzt,
bevor das erste writeUrlState() es ueberschreibt -> Reload bleibt jetzt
wirklich in den Einstellungen.
- Auswahl-Markierungen (Mitglieder/Gruppen-Sichtbar) in Akzentfarbe,
CSS-gezeichnet statt blauer Emoji. Version v28.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Import: Dedupe doppelter UIDs innerhalb der Datei (Nextcloud exportiert
wiederkehrende Termine als mehrere VEVENTs gleicher UID) -> kein
UNIQUE-constraint-500 mehr; Commit abgesichert. Test ergaenzt (15 gruen).
- Picker (Gruppen-Sichtbarkeit + Mitglieder): als <div>-Zeilen statt <label>,
damit die globale ".form-group label"-Uppercase/Grau-Regel das Layout nicht
mehr zerschiesst. Saubere .pick-row-Optik (Checkbox/Radio links, Name links).
- Einstellungen haben jetzt eigenen URL-State (#...&settings=1): Reload/Cache-
leeren bleibt in den Einstellungen statt zur Kalenderansicht zu springen.
- Version v27.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Einstellungen: neuer "Kalender"-Abschnitt – Radio-Auswahl, welcher eigene
Kalender fuer Gruppenmitglieder sichtbar ist (group_visible_calendar_id).
- Sidebar: geteilte Kalender in eigener Sektion "Mit dir geteilt" (mit
Besitzername) statt inline bei "Meine Kalender"; Gruppenkalender dort
ausgeblendet (erscheinen unter Gruppen).
- Lokale Checkbox tolerant: geteilte/Gruppen-Kalender werden client-seitig
ein-/ausgeblendet (kein 404-PUT als Nicht-Besitzer).
- Import-Fehler: zeigt HTTP-Status / "Datei zu gross" statt "unbekannter
Fehler" (z.B. nginx 413). Version v26.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Eigene .group-member-item-Klasse statt der generischen Picker-Klasse —
behebt versetzte Checkboxen / rechtsbuendige Namen. Version v25.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher bekamen /static/js und /static/css max-age=7200. Da index.html
no-cache ist, konnte eine frische HTML mit 2h-altem, gecachtem JS/CSS
gepaart werden — neue Features (z.B. Gruppen-Button) ohne passenden
Handler. JS/CSS revalidieren jetzt bei jedem Load (304 wenn unveraendert);
Icons & uebrige Assets behalten 2h. Deploys greifen so sofort beim Reload.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim letzten Beta->Master-Merge sind die <<<<<<< / ======= / >>>>>>>
Marker mit committet worden. Das hat i18n.js mit einem SyntaxError beim
Parsen abgebrochen und damit den gesamten Frontend-Start kaputt gemacht
(=> komplett schwarze Seite, weil applyTheme nie lief).
Acht Bloecke aufgeloest, in allen Faellen die HEAD-Seite behalten
(neue Features: copy-Key, URL-State, all-day-continues-Logik, Event-
Popup-Header). v22 / sw cache v22.
Vorher waren "Calendarr v18" in index.html hardcoded und wurden bei
Releases nie mit gebumpt — v19/v20 wurden zwar in version.js gepflegt,
landeten aber nie im Tab-Titel. Jetzt liest calendar.js APP_VERSION
direkt aus version.js und setzt sowohl document.title als auch das
Impressum-Footer-Label, damit das nicht mehr auseinanderlaufen kann.
v21 / sw cache v21
- Default-Schriftfarbe = #FFFFFF, Default-Hintergrund = #000000
- Wenn Schrift- und Hintergrundfarbe zu wenig Kontrast haben (< 2.5:1),
wird automatisch auf weiss-auf-schwarz zurueckgefallen. So kann
man sich nicht mehr in eine unsichtbare Seite manoevrieren.
- Color-Picker zeigt jetzt die wirksame Default-Farbe in der Vorschau
(statt leer/transparent), auch wenn keine Override gesetzt ist.
- Live-Vorschau beim Tippen statt erst bei Blur (input-Event)
- Hex-Werte werden auch ohne fuehrendes '#' akzeptiert ("ff0000" -> "#FF0000")
- Reset-Button wendet Standardwerte sofort an
- v19 / sw cache v19
Die bisherigen Stufen-Wähler ("Dunkel/Mittel/Hell/Maximum" und
"Kaum/Subtil/Normal/Stark") für Schrift- bzw. Linienkontrast sind durch
echte Hex-Color-Picker ersetzt. Zusätzlich kann jetzt auch die
Hintergrundfarbe der Seite frei gewählt werden.
Wenn ein Override gesetzt ist:
- text_color → setzt --text-1 direkt, --text-2/--text-3 werden
daraus per shadeHex(-0.25 / -0.55) abgeleitet, damit der Hue passt
- line_color → setzt --border, --border-light wird leicht abgedunkelt
- bg_color → setzt --bg-app, daraus werden Topbar/Sidebar/Surface/
Hover/Active per shadeHex(+0.10…+0.40) konsistent hochskaliert
Per "Reset"-Knopf wird der Override geleert und die alte Stufen-Logik
(falls noch vorhanden) bzw. der Default-Theme greift wieder.
Backend:
- 3 neue nullable VARCHAR(7)-Spalten in user_settings (text_color,
line_color, bg_color) inkl. Migrationen in main.py
- settings_router nutzt model_dump(exclude_unset=True) und respektiert
explizite null-Werte nur für diese 3 Override-Felder, damit Reset
funktioniert
Auch enthalten: Auflösen der Merge-Konflikte in sw.js, index.html,
version.js (HEAD-Stand v17 behalten) und Bump auf v18.
Das Popup hatte vorher Text+Icon-Buttons in einem Footer mit
verschwendeter vertikaler Höhe. Jetzt:
- Color-Dot + Titel links (volle Breite, kann sauber umbrechen)
- Kompakte 30px-Icon-Toolbar rechts oben: Bearbeiten / Kopieren /
Löschen / Schließen
- Icons im Ruhezustand transparent (nur SVG sichtbar, sehr dezent)
- Auf Hover: runder farbiger Hintergrund. Edit/Copy in Primärfarbe,
Delete in Akzentrot, Close in neutralem bg-hover
- Klick gibt mit Scale-Down (.9) taktilen Feedback
- Popup-Breite leicht erhöht (340 → 360 px) damit Titel + Toolbar
bequem nebeneinander passen
- Trash- und Copy-SVG-Pfade auf den 24x24-viewBox normalisiert
(waren vorher zu lang)
Version v16 → v17.
Wenn der Browser noch die alte CSS bzw. i18n.js aus dem Cache hatte,
lief das neu strukturierte Popup ins Leere:
- SVGs ohne CSS-Width-Constraint nahmen die Browser-Standardgröße
(300×150) an → riesige Icons, Layout brach in Vertikalstapel
- Der Key "copy" fehlte in der alten i18n.js → "Kopieren" wurde durch
den Roh-Key "copy" ersetzt
Robust gemacht:
- SVGs der Action-Buttons bekommen jetzt direkt im HTML width="16"
height="16" — funktioniert auch ohne dass die zugehörige CSS-Regel
geladen wurde
- applyLang() in i18n.js fällt bei fehlendem Schlüssel auf den
HTML-Default-Text zurück, anstatt den Key als Text einzuschreiben
(gleiches Prinzip für data-i18n, -i18n-ph, -i18n-title)
Version v15 → v16.
Vorher haben Bearbeiten/Kopieren/Löschen/Schließen im Header über die
Hälfte der Breite gefressen, sodass der Titel auf 2-3 Zeilen
zusammenschrumpfen musste.
Neues Layout:
- Schließen-X klein in der oberen rechten Ecke (absolut positioniert)
- Header zeigt nur Color-Dot + Titel — voller Platz fürs Lesen
- Drei beschriftete Aktions-Buttons (Bearbeiten / Kopieren / Löschen)
als gleichbreite Reihe im Footer
- Hover-Tint folgt der Primärfarbe; Löschen tönt zur Akzentfarbe
- Popup-Breite leicht erhöht (300 → 340 px) für mehr Atemraum
- Mobile bekommt die Action-Buttons etwas kompakter
IDs der Buttons unverändert (popup-edit/copy/delete/close), bestehende
JS-Handler funktionieren weiter.
Version v14 → v15.
Die drei Aktions-Icons (Bearbeiten, Kopieren, Löschen) und der
Schließen-X im Termin-Popup hatten bisher nur den schlichten
icon-btn-Hover (graue Fläche). Jetzt im selben modernen Stil wie die
neuen Pill-Buttons:
- Bearbeiten/Kopieren/Löschen: Hover bekommt Primärfarben-Tint
(color-mix-Hintergrund + farbige Schrift) plus dezenten farbigen
Schatten
- Schließen-X: Hover zeigt die Akzentfarbe (rot), passend zur
destruktiven Geste
- Klick fühlt sich mit kurzem Scale-Down (.92) taktiler an
Version v13 → v14.
Großes Frontend-Update für alle Buttons. Der Stil orientiert sich an
modernen App-Designs (Pill mit dezentem Schatten, sanft "abhebender"
Hover-Effekt), die Farbe folgt der gewählten Primärfarbe des Users
dynamisch via color-mix().
- .btn: fully rounded (border-radius: 999px), grösseres Padding,
smooth Transitions für Schatten/Transform/Brightness
- .btn-primary: Primärfarbe als Hintergrund + dezenter farbiger
Schatten; Hover hebt um 1px, Schatten wird kräftiger, leichte
Aufhellung
- .btn-secondary: dezenter Border, auf Hover wird er primär-farben
- .btn-ghost / .btn-danger entsprechend angepasst
- .btn-fab (Sidebar "Erstellen"): jetzt in Primärfarbe statt grau,
passt zum FAB unten rechts auf Mobile und zur Marken-Sprache
- .icon-btn: kleines Scale-Down beim Drücken, Focus-Ring sichtbar
für Tastatur-Nutzer
- Form-Inputs: 8px Radius, sanfter Hover-Border, beim Focus jetzt
Primärfarben-Ring (color-mix-Glow)
Fix: kaputtes Plus-SVG am Kalender-Hinzufügen-Button — Vertikalbalken
war zu lang (v12 statt v6), jetzt symmetrisch.
Version v12 → v13.
Bisher konnten alte JS-/CSS-Dateien durch Service-Worker- und Browser-
Cache hartnäckig hängen bleiben, obwohl auf dem Server schon eine neue
Version lag. Strategie jetzt:
Backend (main.py)
- Neue HTTP-Middleware setzt explizite Cache-Control-Header:
* /, /index.html, /manifest.json, /sw.js, /static/js/version.js
bekommen no-cache, no-store, must-revalidate
* /static/* und /icons/* bekommen public, max-age=7200,
must-revalidate (2 h)
* SPA-Fallback-Antworten ebenfalls no-cache
* /api/* bleibt unangetastet
Service Worker (sw.js)
- Wechsel von Cache-First zu Network-First für alles
- Cache wird nur noch für die index.html-Offline-Hülle vorgehalten,
nicht mehr für JS/CSS — Browser-HTTP-Cache übernimmt das mit den
2-h-Headern vom Server
- Bei Netzwerkfehler bleibt nur die HTML-Shell offline verfügbar
Version v11 → v12 (auch SW-Cache-Key).
Bisher bekam nur .topbar Safe-Area-Padding, aber .content-wrapper
rechnete weiter starr mit --topbar-h. Im PWA-Standalone-Modus auf
iPhones mit Notch lief der Kalender dadurch oben in die Status-Bar
und unten in den Home-Indicator hinein — die Wochentag-Header und
Tagesnummern der ersten Zeile waren verdeckt, die letzte Zeile
zu kurz.
- .content-wrapper: margin-top und height berechnen jetzt safe-top
und safe-bottom mit ein
- .sidebar (Mobile-Overlay): top startet ebenfalls unterhalb der
vergrösserten Topbar
Version v10 → v11.
Bisher bekam nur .topbar Safe-Area-Padding, aber .content-wrapper
rechnete weiter starr mit --topbar-h. Im PWA-Standalone-Modus auf
iPhones mit Notch lief der Kalender dadurch oben in die Status-Bar
und unten in den Home-Indicator hinein — die Wochentag-Header und
Tagesnummern der ersten Zeile waren verdeckt, die letzte Zeile
zu kurz.
- .content-wrapper: margin-top und height berechnen jetzt safe-top
und safe-bottom mit ein
- .sidebar (Mobile-Overlay): top startet ebenfalls unterhalb der
vergrösserten Topbar
Version v10 → v11.
- Erstellen-Button in der Sidebar: SVG-Path war asymmetrisch
(M19 13h-6v9...) — Vertikalbalken hing nach unten heraus. Jetzt
Standard-Plus mit gleich langen Armen.
- Service Worker holt index.html und version.js ab sofort per
Network-First — neue Releases greifen damit beim nächsten
Seiten-Reload, ohne dass der SW manuell deregistriert werden muss.
Statics bleiben Cache-First für Offline-Tauglichkeit; auf
Aktivierung wird der alte Cache komplett gelöscht.
Version v9 → v10.
- Erstellen-Button in der Sidebar: SVG-Path war asymmetrisch
(M19 13h-6v9...) — Vertikalbalken hing nach unten heraus. Jetzt
Standard-Plus mit gleich langen Armen.
- Service Worker holt index.html und version.js ab sofort per
Network-First — neue Releases greifen damit beim nächsten
Seiten-Reload, ohne dass der SW manuell deregistriert werden muss.
Statics bleiben Cache-First für Offline-Tauglichkeit; auf
Aktivierung wird der alte Cache komplett gelöscht.
Version v9 → v10.
- Titel im Topbar wird auf Mobile auf 2 Zeilen aufgeteilt: Hauptlabel
(z.B. "Mai – Jun") oben, Jahr ("2026") darunter in kleinerer Schrift.
Auf Desktop bleibt es einzeilig durch margin-left auf der Year-Span.
- Event-Popup: 44px-Mindestgröße der Icon-Buttons greift hier nicht
mehr — Buttons bleiben kompakt 32px, weniger Gap, schmaleres Popup
(max 92vw / 340px), sodass das Schließen-X nicht aus dem Rand
herausragt.
- Monatsansicht auf Mobile: Startuhrzeit ("00:00 Lemgo") wird
versteckt, nur der Titel ist sichtbar. Auf Desktop wie bisher mit
Uhrzeit-Präfix. Die Info bleibt im Termin-Popup verfügbar.
Version v8 → v9.
- Titel im Topbar wird auf Mobile auf 2 Zeilen aufgeteilt: Hauptlabel
(z.B. "Mai – Jun") oben, Jahr ("2026") darunter in kleinerer Schrift.
Auf Desktop bleibt es einzeilig durch margin-left auf der Year-Span.
- Event-Popup: 44px-Mindestgröße der Icon-Buttons greift hier nicht
mehr — Buttons bleiben kompakt 32px, weniger Gap, schmaleres Popup
(max 92vw / 340px), sodass das Schließen-X nicht aus dem Rand
herausragt.
- Monatsansicht auf Mobile: Startuhrzeit ("00:00 Lemgo") wird
versteckt, nur der Titel ist sichtbar. Auf Desktop wie bisher mit
Uhrzeit-Präfix. Die Info bleibt im Termin-Popup verfügbar.
Version v8 → v9.
- "Heute"-Button auf Mobile wieder im Topbar-Center sichtbar
(kompakter mit weniger Padding) statt nur im View-Popup.
- Neuer runder Floating-Action-Button unten rechts auf Mobile mit
Plus-Icon, öffnet das "Termin erstellen"-Modal — Google-Calendar-
artige Bedienung.
- Der "Erstellen"-Button in der Sidebar wird auf Mobile ausgeblendet,
weil der FAB ihn ersetzt. Auf Desktop bleibt alles wie bisher.
- iOS-Safe-Area unten respektiert (Home-Indicator).
Version v7 → v8.
- "Heute"-Button auf Mobile wieder im Topbar-Center sichtbar
(kompakter mit weniger Padding) statt nur im View-Popup.
- Neuer runder Floating-Action-Button unten rechts auf Mobile mit
Plus-Icon, öffnet das "Termin erstellen"-Modal — Google-Calendar-
artige Bedienung.
- Der "Erstellen"-Button in der Sidebar wird auf Mobile ausgeblendet,
weil der FAB ihn ersetzt. Auf Desktop bleibt alles wie bisher.
- iOS-Safe-Area unten respektiert (Home-Indicator).
Version v7 → v8.
Damit lädt beim Swipen durch Monate erst nach ~10 Monaten in beide
Richtungen erneut Daten nach. Vorher reichte der Cache nur ±2 Monate,
sodass nach 2-3 Wischen ein Spinner kam.
- CACHE_BUF 56 → 300 Tage (initial ±10 Monate)
- PREFETCH_EXT 56 → 180 Tage (Verlängerung bei Edge ~6 Monate)
- PREFETCH_EDGE 28 → 90 Tage (Trigger ~3 Monate vor Cache-Rand)
Version v6 → v7.
Damit lädt beim Swipen durch Monate erst nach ~10 Monaten in beide
Richtungen erneut Daten nach. Vorher reichte der Cache nur ±2 Monate,
sodass nach 2-3 Wischen ein Spinner kam.
- CACHE_BUF 56 → 300 Tage (initial ±10 Monate)
- PREFETCH_EXT 56 → 180 Tage (Verlängerung bei Edge ~6 Monate)
- PREFETCH_EDGE 28 → 90 Tage (Trigger ~3 Monate vor Cache-Rand)
Version v6 → v7.
Wenn aktiviert, bekommt der JWT-Token statt der üblichen 7 Tage eine
Lebensdauer von 180 Tagen. Der Token liegt wie bisher in localStorage,
bleibt also bis zum manuellen Löschen / Cookie-Reset gültig.
- backend/routers/auth_router.py: LoginRequest.remember_me, längere
expires_delta beim Token-Erstellen
- index.html: Checkbox unter dem 2FA-Feld
- api.js: login() reicht remember_me als 4. Parameter durch
- app.js: Wert aus #login-remember lesen und mitschicken
- Version v5 → v6
Wenn aktiviert, bekommt der JWT-Token statt der üblichen 7 Tage eine
Lebensdauer von 180 Tagen. Der Token liegt wie bisher in localStorage,
bleibt also bis zum manuellen Löschen / Cookie-Reset gültig.
- backend/routers/auth_router.py: LoginRequest.remember_me, längere
expires_delta beim Token-Erstellen
- index.html: Checkbox unter dem 2FA-Feld
- api.js: login() reicht remember_me als 4. Parameter durch
- app.js: Wert aus #login-remember lesen und mitschicken
- Version v5 → v6
- View-Switcher auf Mobile in Popup-Menü ausgelagert (neuer Icon-Button
rechts in der Topbar). Dadurch wird in der Topbar Platz frei für
prev/next + Monatstitel ("Mai 2026" usw.).
- Topbar-Settings-Icon auf Mobile ausgeblendet, dafür neuer
"Einstellungen"-Eintrag im User-Dropdown. "Heute" wandert ins
View-Popup.
- KW-Bubble: von oben-links nach unten-links verschoben — überlappt
jetzt nicht mehr die Tagesnummer.
- Termine in der Monatsansicht zeigen wieder ihren Text (kleinere
14px-Höhe, 9px Schrift) statt nur farbiger Punkte.
- Long-Press auf einen Tag öffnet das Kontextmenü "Termin erstellen"
(synthetisches contextmenu-Event nach 500 ms ohne Bewegung). Der
nachfolgende synthetische Click wird unterdrückt.
- Settings-Modal: Sidebar (Darstellung/Konten/Benutzerverwaltung) auf
Mobile als slide-in Overlay mit Hamburger-Toggle. Auf Desktop bleibt
sie immer sichtbar.
- Version v4 → v5 (auch SW-Cache)
- View-Switcher auf Mobile in Popup-Menü ausgelagert (neuer Icon-Button
rechts in der Topbar). Dadurch wird in der Topbar Platz frei für
prev/next + Monatstitel ("Mai 2026" usw.).
- Topbar-Settings-Icon auf Mobile ausgeblendet, dafür neuer
"Einstellungen"-Eintrag im User-Dropdown. "Heute" wandert ins
View-Popup.
- KW-Bubble: von oben-links nach unten-links verschoben — überlappt
jetzt nicht mehr die Tagesnummer.
- Termine in der Monatsansicht zeigen wieder ihren Text (kleinere
14px-Höhe, 9px Schrift) statt nur farbiger Punkte.
- Long-Press auf einen Tag öffnet das Kontextmenü "Termin erstellen"
(synthetisches contextmenu-Event nach 500 ms ohne Bewegung). Der
nachfolgende synthetische Click wird unterdrückt.
- Settings-Modal: Sidebar (Darstellung/Konten/Benutzerverwaltung) auf
Mobile als slide-in Overlay mit Hamburger-Toggle. Auf Desktop bleibt
sie immer sichtbar.
- Version v4 → v5 (auch SW-Cache)
- Viewport: maximum-scale=1, user-scalable=no — kein Pinch-Zoom mehr
- Profil-Dropdown öffnet wieder: overflow:hidden auf .topbar-right
in der Mobile-Media-Query entfernt (hatte das absolut positionierte
Dropdown abgeschnitten)
- Long-Press auf Kalenderzellen markiert keinen Text mehr:
user-select/touch-callout/tap-highlight in der ganzen Mobile-UI aus
- Long-Press auf Avatar zeigt nicht "Bild speichern":
-webkit-touch-callout:none + pointer-events:none auf <img>
- Kalenderwochen erscheinen als kleine Bubble oben links in jeder
Zeile statt als eigene 38px-Spalte
- Status-Bar-Overlap im Settings-Modal behoben: safe-area-inset-top
auf .settings-page-header und Modal-Header in der Mobile-Media-Query
- Swipe links/rechts auf #view-container navigiert prev/next
(≥60 px, überwiegend horizontal, < 700 ms)
- Version v3 → v4 (auch SW-Cache)
- Viewport: maximum-scale=1, user-scalable=no — kein Pinch-Zoom mehr
- Profil-Dropdown öffnet wieder: overflow:hidden auf .topbar-right
in der Mobile-Media-Query entfernt (hatte das absolut positionierte
Dropdown abgeschnitten)
- Long-Press auf Kalenderzellen markiert keinen Text mehr:
user-select/touch-callout/tap-highlight in der ganzen Mobile-UI aus
- Long-Press auf Avatar zeigt nicht "Bild speichern":
-webkit-touch-callout:none + pointer-events:none auf <img>
- Kalenderwochen erscheinen als kleine Bubble oben links in jeder
Zeile statt als eigene 38px-Spalte
- Status-Bar-Overlap im Settings-Modal behoben: safe-area-inset-top
auf .settings-page-header und Modal-Header in der Mobile-Media-Query
- Swipe links/rechts auf #view-container navigiert prev/next
(≥60 px, überwiegend horizontal, < 700 ms)
- Version v3 → v4 (auch SW-Cache)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Macht Calendarr installierbar (Manifest + Service Worker) und auf
Smartphones bedienbar — additive Änderungen, kein Refactoring der
bestehenden Logik, Theme/Variablen unverändert.
PWA:
- frontend/manifest.json (theme #4285f4, bg #0e0e14, name/icons/scope)
- frontend/sw.js (cache-first für Statics, network-first für /api/*)
- frontend/icons/icon-192.png + icon-512.png + icon.svg
- backend/main.py: Routen für /manifest.json, /sw.js, /icons/* damit
diese Pfade nicht vom SPA-Fallback abgefangen werden
- index.html: manifest-Link, theme-color, apple-touch-icon, apple-* Meta
- app.js: Service-Worker-Registrierung am Ende
Mobile (≤ 768px, additiv am Ende von app.css):
- Sidebar als Overlay mit body.sidebar-open + Backdrop-Element
- View-Switcher horizontal scrollbar wenn er nicht passt
- Monatsansicht zeigt nur farbige Punkte statt Titel
- Wochenansicht reduziert auf Tagesspalte (heute) wenn heute in der
Woche ist (via :has()), sonst Standard-7-Spalten
- Modale auf voller Breite/Höhe
- Tap-Targets ≥ 44px (icon-btn, btn)
- Kein horizontaler Page-Overflow
- iOS-Safe-Area für Notch/Home-Indicator
Version v2 → v3.
Macht Calendarr installierbar (Manifest + Service Worker) und auf
Smartphones bedienbar — additive Änderungen, kein Refactoring der
bestehenden Logik, Theme/Variablen unverändert.
PWA:
- frontend/manifest.json (theme #4285f4, bg #0e0e14, name/icons/scope)
- frontend/sw.js (cache-first für Statics, network-first für /api/*)
- frontend/icons/icon-192.png + icon-512.png + icon.svg
- backend/main.py: Routen für /manifest.json, /sw.js, /icons/* damit
diese Pfade nicht vom SPA-Fallback abgefangen werden
- index.html: manifest-Link, theme-color, apple-touch-icon, apple-* Meta
- app.js: Service-Worker-Registrierung am Ende
Mobile (≤ 768px, additiv am Ende von app.css):
- Sidebar als Overlay mit body.sidebar-open + Backdrop-Element
- View-Switcher horizontal scrollbar wenn er nicht passt
- Monatsansicht zeigt nur farbige Punkte statt Titel
- Wochenansicht reduziert auf Tagesspalte (heute) wenn heute in der
Woche ist (via :has()), sonst Standard-7-Spalten
- Modale auf voller Breite/Höhe
- Tap-Targets ≥ 44px (icon-btn, btn)
- Kein horizontaler Page-Overflow
- iOS-Safe-Area für Notch/Home-Indicator
Version v2 → v3.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Home Assistant unterstützt keinen Password-Grant — deshalb kam immer
"Ungültige Anmeldedaten", egal was eingegeben wurde. Jetzt wird der
Nutzer nach demselben Muster wie bei Google zur HA-Login-Seite
weitergeleitet, meldet sich dort an und kommt zurück zu Calendarr.
Änderungen:
- Neuer POST /api/homeassistant/auth-url und GET /callback Endpoint
- Account speichert client_id für spätere Token-Refreshes
- Modal: "Benutzername/Passwort" → "Mit Home Assistant anmelden"
- Frontend behandelt ?ha_connected=1 / ?ha_error=... nach Rückkehr
- Version v1 → v2
Home Assistant unterstützt keinen Password-Grant — deshalb kam immer
"Ungültige Anmeldedaten", egal was eingegeben wurde. Jetzt wird der
Nutzer nach demselben Muster wie bei Google zur HA-Login-Seite
weitergeleitet, meldet sich dort an und kommt zurück zu Calendarr.
Änderungen:
- Neuer POST /api/homeassistant/auth-url und GET /callback Endpoint
- Account speichert client_id für spätere Token-Refreshes
- Modal: "Benutzername/Passwort" → "Mit Home Assistant anmelden"
- Frontend behandelt ?ha_connected=1 / ?ha_error=... nach Rückkehr
- Version v1 → v2
Neue version.js als Single Point of Truth (APP_VERSION).
Sidebar, Login-Screen und Impressum-Modal zeigen die aktuelle
Version an — ab jetzt bei jeder Änderung v2, v3 ... hochzählen.
Startet bei v1.
Neue version.js als Single Point of Truth (APP_VERSION).
Sidebar, Login-Screen und Impressum-Modal zeigen die aktuelle
Version an — ab jetzt bei jeder Änderung v2, v3 ... hochzählen.
Startet bei v1.