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>
iCal speichert DTEND exklusiv (Tag NACH dem letzten Tag). Bisher
führte das dazu, dass ein Termin mit Ende=18.08 nur bis zum 17.08
angezeigt wurde, obwohl der User 18.08 als letzten Tag erwartete.
Fix: Im Date-Picker arbeiten wir jetzt mit inklusiven End-Daten
('endet am 18.08' = 18.08 ist letzter Tag) und konvertieren beim
Speichern auf exklusiv (DTEND=19.08). Beim Laden umgekehrt: -1 Tag
fürs Anzeigen im Picker.
Betrifft: openEditEventModal, openCopyEditModal, Save-Handler.
iCal speichert DTEND exklusiv (Tag NACH dem letzten Tag). Bisher
führte das dazu, dass ein Termin mit Ende=18.08 nur bis zum 17.08
angezeigt wurde, obwohl der User 18.08 als letzten Tag erwartete.
Fix: Im Date-Picker arbeiten wir jetzt mit inklusiven End-Daten
('endet am 18.08' = 18.08 ist letzter Tag) und konvertieren beim
Speichern auf exklusiv (DTEND=19.08). Beim Laden umgekehrt: -1 Tag
fürs Anzeigen im Picker.
Betrifft: openEditEventModal, openCopyEditModal, Save-Handler.
Über der Kalenderliste im Kopieren-Menü gibt es jetzt eine Checkbox
'Vor dem Kopieren bearbeiten'. Wenn aktiviert und ein Ziel-Kalender
geklickt wird, öffnet sich der Termin-erstellen-Dialog mit allen
Daten des Quell-Termins vorausgefüllt (Titel, Datum, Ort, Beschreibung,
Farbe, Wiederholung) und dem Ziel-Kalender vorausgewählt.
Über der Kalenderliste im Kopieren-Menü gibt es jetzt eine Checkbox
'Vor dem Kopieren bearbeiten'. Wenn aktiviert und ein Ziel-Kalender
geklickt wird, öffnet sich der Termin-erstellen-Dialog mit allen
Daten des Quell-Termins vorausgefüllt (Titel, Datum, Ort, Beschreibung,
Farbe, Wiederholung) und dem Ziel-Kalender vorausgewählt.
- populateCalendarSelect: filtert jetzt nach !sidebar_hidden statt
enabled. Unchecked (versteckte) Kalender bleiben so im
Termin-erstellen-Dropdown verfügbar
- buildWritableCalendars: HA-Kalender werden als Kopier-Ziele aufgeführt
- copyEventToCalendar: routet HA-Ziele über /homeassistant/events
Endpoint (vorher fielen sie in den CalDAV-Fallback)
- populateCalendarSelect: filtert jetzt nach !sidebar_hidden statt
enabled. Unchecked (versteckte) Kalender bleiben so im
Termin-erstellen-Dropdown verfügbar
- buildWritableCalendars: HA-Kalender werden als Kopier-Ziele aufgeführt
- copyEventToCalendar: routet HA-Ziele über /homeassistant/events
Endpoint (vorher fielen sie in den CalDAV-Fallback)
Nach dem Speichern eines Termins wird das gecachte Event-Objekt
direkt in-place gepatcht und die View neu gerendert. Vorher war die
neue Farbe erst nach F5 sichtbar, weil zwar fetchAndRender(true)
aufgerufen wurde, aber der Render-Pfad das Update nicht zuverlässig
übernommen hat.
Nach dem Speichern eines Termins wird das gecachte Event-Objekt
direkt in-place gepatcht und die View neu gerendert. Vorher war die
neue Farbe erst nach F5 sichtbar, weil zwar fetchAndRender(true)
aufgerufen wurde, aber der Render-Pfad das Update nicht zuverlässig
übernommen hat.
- POST /api/homeassistant/events Endpoint mit calendar.create_event
- Frontend: HA-Termine erstellen statt 'nicht unterstützt' Toast
- Datetime-Format an HA-Konvention angepasst:
'YYYY-MM-DD HH:MM:SS' (Space-Separator, ohne Timezone)
- _ha_format_dt Helper für ISO → HA Datetime-Konvertierung
- POST /api/homeassistant/events Endpoint mit calendar.create_event
- Frontend: HA-Termine erstellen statt 'nicht unterstützt' Toast
- Datetime-Format an HA-Konvention angepasst:
'YYYY-MM-DD HH:MM:SS' (Space-Separator, ohne Timezone)
- _ha_format_dt Helper für ISO → HA Datetime-Konvertierung
- HA Update/Delete: UID wird URL-encoded (@ → %40), Delete mit
Fallback auf Service-Call API für ältere HA-Versionen
- Lösch-Dialog: Event-Popup wird geschlossen BEVOR der Bestätigungsdialog
erscheint, kein Überlappen mehr
- HA Update/Delete: UID wird URL-encoded (@ → %40), Delete mit
Fallback auf Service-Call API für ältere HA-Versionen
- Lösch-Dialog: Event-Popup wird geschlossen BEVOR der Bestätigungsdialog
erscheint, kein Überlappen mehr
- HA-Events: Update/Delete-Endpoints via HA REST API implementiert
- HA read-only Guard entfernt, stattdessen korrekte API-Anbindung
- Selected-Day: Outline-Ring statt gefüllter Kreis (Today bleibt gefüllt)
- Serien-Löschung: RECURRENCE-ID aus CalDAV-Events erkennen, damit
expandierte Serientermine als recurring markiert werden und der
Lösch-Dialog Einzel-/Serienlöschung anbietet
- HA-Events: Update/Delete-Endpoints via HA REST API implementiert
- HA read-only Guard entfernt, stattdessen korrekte API-Anbindung
- Selected-Day: Outline-Ring statt gefüllter Kreis (Today bleibt gefüllt)
- Serien-Löschung: RECURRENCE-ID aus CalDAV-Events erkennen, damit
expandierte Serientermine als recurring markiert werden und der
Lösch-Dialog Einzel-/Serienlöschung anbietet
- caldav_client: del+add statt direkter Zuweisung bei VEVENT-Properties
(behebt "DTSTART MUST appear exactly once" Validierungsfehler)
- HA-Events als read-only behandeln (kein Bearbeiten/Löschen im Popup)
- [object Object] Toast behoben: HA-Events fallen nicht mehr in CalDAV-Pfad
- caldav_client: del+add statt direkter Zuweisung bei VEVENT-Properties
(behebt "DTSTART MUST appear exactly once" Validierungsfehler)
- HA-Events als read-only behandeln (kein Bearbeiten/Löschen im Popup)
- [object Object] Toast behoben: HA-Events fallen nicht mehr in CalDAV-Pfad
- End-Datum passt sich automatisch an wenn Start geändert wird (Duration bleibt erhalten)
- Erstellen-Button nutzt den aktuell angesehenen Tag statt immer heute
- Monatsansicht: Einzelklick = Tag auswählen, Doppelklick = Tagesansicht, Rechtsklick = Kontextmenü
- CalDAV URL-Matching robuster (Normalisierung, Path-Fallback, calendar_id Parameter)
- iCal-Abo-Termine sind nicht mehr bearbeitbar (Read-Only-Schutz)
- Wiederkehrende Termine mit RRULE-Support (täglich/wöchentlich/monatlich/jährlich/benutzerdefiniert)
- End-Datum passt sich automatisch an wenn Start geändert wird (Duration bleibt erhalten)
- Erstellen-Button nutzt den aktuell angesehenen Tag statt immer heute
- Monatsansicht: Einzelklick = Tag auswählen, Doppelklick = Tagesansicht, Rechtsklick = Kontextmenü
- CalDAV URL-Matching robuster (Normalisierung, Path-Fallback, calendar_id Parameter)
- iCal-Abo-Termine sind nicht mehr bearbeitbar (Read-Only-Schutz)
- Wiederkehrende Termine mit RRULE-Support (täglich/wöchentlich/monatlich/jährlich/benutzerdefiniert)
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
Vorher wurde die Version erst in initCalendar() gesetzt – wenn JS
vorher fehlschlug, blieb der Text leer. Jetzt steht v1 direkt im
HTML (Titel, Login-Button, Sidebar-Button, Impressum-Modal).
Für künftige Releases: v1 → v2 in index.html + version.js ersetzen.
Vorher wurde die Version erst in initCalendar() gesetzt – wenn JS
vorher fehlschlug, blieb der Text leer. Jetzt steht v1 direkt im
HTML (Titel, Login-Button, Sidebar-Button, Impressum-Modal).
Für künftige Releases: v1 → v2 in index.html + version.js ersetzen.
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.
- Backend gibt 400 statt 401 bei falschen HA-Credentials zurück, damit
der globale api.js-Logout-Handler nicht ausgelöst wird
- Null-Guard im JS nach api.post verhindert den "calendars of null"-Crash
- Radio-Buttons für Anmeldemethode nicht mehr in form-group, damit
input[type=radio] kein width:100% bekommt und sauber nebeneinander liegt
- Backend gibt 400 statt 401 bei falschen HA-Credentials zurück, damit
der globale api.js-Logout-Handler nicht ausgelöst wird
- Null-Guard im JS nach api.post verhindert den "calendars of null"-Crash
- Radio-Buttons für Anmeldemethode nicht mehr in form-group, damit
input[type=radio] kein width:100% bekommt und sauber nebeneinander liegt
Ergänzt die HA-Integration um Password-Grant OAuth2: Nutzer können sich
nun wahlweise mit einem Long-Lived Token oder mit Benutzername/Passwort
anmelden. Access Tokens werden automatisch per Refresh-Token erneuert.
Ergänzt die HA-Integration um Password-Grant OAuth2: Nutzer können sich
nun wahlweise mit einem Long-Lived Token oder mit Benutzername/Passwort
anmelden. Access Tokens werden automatisch per Refresh-Token erneuert.
Der Cursor war relativ zum .gcp-Container positioniert, aber ohne den
Offset des Canvas innerhalb des Containers (Padding). Jetzt wird die
Canvas-Position via getBoundingClientRect() eingerechnet, sodass der
Cursor exakt auf der Farbpalette bleibt.