From 3962074af6861e7438abecd2cb74dfe07584e389 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 21:31:33 +0000 Subject: [PATCH] =?UTF-8?q?Kundenansicht=20neu=20E-Fix=20F3b:=20Safe-Area?= =?UTF-8?q?=20links=20und=20rechts=20in=20H=C3=BClle,=20=C3=B6ffentlichen?= =?UTF-8?q?=20Seiten=20und=20Chat-Vollbild?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dashboard.html und die öffentlichen Seiten setzen viewport-fit=cover, aber kein Rand nutzte env(safe-area-inset-left|right): Im Querformat am iPhone rutschten die ersten Zeichen unter Notch und Insel. Kopf, Hauptseite, Blatt, Streifen, Konto-Sheet, Fehlerzeile, Leiste, Banner und die Sperre sowie Login, Rechtsseiten, Auftrag, Offline-Seite und die Kopfzeile des Chat-Vollbilds bauen ihre Ränder jetzt mit max(Wert, env(safe-area-inset-left|right)). Am Desktop und ohne Notch ändert sich nichts (Inset 0). Pins in test/knEfixCss.test.js. Co-Authored-By: Claude Sonnet 5.5 --- public/neu/chat-composer.css | 2 +- public/neu/huelle.css | 18 +++++++++--------- public/neu/oeffentlich/oeffentlich.css | 10 +++++----- public/neu/oeffentlich/offline.html | 2 +- test/knEfixCss.test.js | 13 +++++++++++++ 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/public/neu/chat-composer.css b/public/neu/chat-composer.css index 9eae6b1..e610741 100644 --- a/public/neu/chat-composer.css +++ b/public/neu/chat-composer.css @@ -182,7 +182,7 @@ html.chat-overlay-open, html.chat-overlay-open body { overflow: hidden; } position: fixed; inset: 0; z-index: 1000; display: flex; flex-direction: column; background: rgba(4, 4, 6, 0.95); color: #fff; font-family: inherit; } -.chat-ov-top { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px 14px; padding-top: max(12px, env(safe-area-inset-top)); } +.chat-ov-top { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px max(14px, env(safe-area-inset-right)) 12px max(14px, env(safe-area-inset-left)); padding-top: max(12px, env(safe-area-inset-top)); } .chat-ov-title { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .chat-ov-btn { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-width: 44px; height: 44px; padding: 0 12px; diff --git a/public/neu/huelle.css b/public/neu/huelle.css index a94ceb8..9ced136 100644 --- a/public/neu/huelle.css +++ b/public/neu/huelle.css @@ -38,7 +38,7 @@ .kn-tastatur .kn-streifen { display: none; } @media (max-width: 880px), (pointer: coarse) and (max-height: 500px) { - .kn-streifen { position: fixed; left: 0; right: 0; bottom: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom)); z-index: 30; padding: 0 16px; } + .kn-streifen { position: fixed; left: 0; right: 0; bottom: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom)); z-index: 30; padding: 0 max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); } .kn-streifen-link { min-height: 44px; display: inline-flex; align-items: center; } .kn-hat-streifen { --kn-unten: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom) + 44px); } .kn-hat-streifen .kn-haupt { padding-bottom: calc(var(--kn-zeile-h) + env(safe-area-inset-bottom) + 28px + 44px); } @@ -70,7 +70,7 @@ @media (max-width: 880px), (pointer: coarse) and (max-height: 500px) { .kn-konto-scrim { background: var(--kn-overlay); animation: kn-einblenden .3s ease-out; } - .kn-konto { top: auto; right: 0; bottom: 0; left: 0; width: auto; max-height: 92vh; padding: 8px 20px calc(22px + env(safe-area-inset-bottom)); border-radius: 12px 12px 0 0; animation: kn-sheet-hoch 500ms var(--kn-bremse); } + .kn-konto { top: auto; right: 0; bottom: 0; left: 0; width: auto; max-height: 92vh; padding: 8px max(20px, env(safe-area-inset-right)) calc(22px + env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left)); border-radius: 12px 12px 0 0; animation: kn-sheet-hoch 500ms var(--kn-bremse); } .kn-konto-zu { min-height: 44px; } .kn-konto-zeile { min-height: 46px; } } @@ -80,7 +80,7 @@ public/kundenansicht.js hängt bei 409 view_replaced bzw. 401 view_expired ein div.kb-view-overlay (role alertdialog) an den Body. Die alte Seite gestaltet es in kundenbereich.css, die dashboard.html nicht lädt: hier die Regeln für die neue Seite. Deckend weiß über allem (Konto 60, Leiste 40), damit nichts Veraltetes bedienbar bleibt. */ -.kb-view-overlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: max(24px, env(safe-area-inset-top)) 24px max(24px, env(safe-area-inset-bottom)); background: var(--kn-bg); } +.kb-view-overlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: max(24px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left)); background: var(--kn-bg); } .kb-view-overlay-card { width: 100%; max-width: 420px; text-align: center; } .kb-view-overlay-card p { margin: 0 0 24px; font-size: 17px; line-height: 26px; color: var(--kn-text); } .kb-view-overlay-card button { min-height: 44px; padding: 0 24px; border-radius: var(--kn-radius); background: var(--kn-accent); color: #fff; font-weight: 600; box-shadow: var(--kn-shadow-btn); } @@ -94,7 +94,7 @@ .kn-skip:focus { top: 8px; } .kn-nur-leser { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; } -.kn-banner { position: relative; z-index: 30; display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 36px; padding: 6px 16px; background: var(--kn-accent); color: #fff; font-size: 13px; line-height: 20px; } +.kn-banner { position: relative; z-index: 30; display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 36px; padding: 6px max(16px, env(safe-area-inset-right)) 6px max(16px, env(safe-area-inset-left)); background: var(--kn-accent); color: #fff; font-size: 13px; line-height: 20px; } .kn-banner > span { min-width: 0; overflow-wrap: anywhere; } .kn-banner button { flex: none; min-height: 28px; padding: 0 4px; color: #fff; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; } .kn-banner:not([hidden]) ~ .kn-huelle .kn-menue { top: 36px; } @@ -123,22 +123,22 @@ @media (max-width: 880px), (pointer: coarse) and (max-height: 500px) { .kn-menue { display: none; } .kn-spalte { margin-left: 0; } - .kn-kopf { justify-content: space-between; height: auto; min-height: calc(var(--kn-kopf-h) + env(safe-area-inset-top)); margin-bottom: 0; padding: env(safe-area-inset-top) 8px 0 20px; border-bottom: 1px solid transparent; background: var(--kn-bg); transition: border-color 300ms; pointer-events: auto; } + .kn-kopf { justify-content: space-between; height: auto; min-height: calc(var(--kn-kopf-h) + env(safe-area-inset-top)); margin-bottom: 0; padding: env(safe-area-inset-top) max(8px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left)); border-bottom: 1px solid transparent; background: var(--kn-bg); transition: border-color 300ms; pointer-events: auto; } .kn-scrolled .kn-kopf { border-bottom-color: var(--kn-line); } .kn-kopf-titel { display: block; font-size: 15px; line-height: 22px; font-weight: 600; opacity: 0; transform: translateY(5px); transition: opacity 250ms, transform 250ms; } .kn-titled .kn-kopf-titel { opacity: 1; transform: none; } - .kn-haupt { max-width: none; padding: 2px 16px calc(var(--kn-zeile-h) + env(safe-area-inset-bottom) + 28px); } - .kn-blatt { max-width: none; padding: 0 16px 24px; } + .kn-haupt { max-width: none; padding: 2px max(16px, env(safe-area-inset-right)) calc(var(--kn-zeile-h) + env(safe-area-inset-bottom) + 28px) max(16px, env(safe-area-inset-left)); } + .kn-blatt { max-width: none; padding: 0 max(16px, env(safe-area-inset-right)) 24px max(16px, env(safe-area-inset-left)); } .kn-haupt .kn-titel, .kn-blatt .kn-titel { margin: 6px 0 10px; font-size: 28px; line-height: 34px; } .kn-banner button { min-height: 44px; } - #kn-fehler { margin: 12px 16px 0; } + #kn-fehler { margin: 12px max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); } } /* ---------- Leiste (Handy): Fahrstuhl-Zeile mit Balken ---------- */ .kn-leiste { display: none; } .kn-leiste-reel { height: var(--kn-zeile-h); overflow: hidden; } -.kn-rw { display: flex; align-items: center; height: var(--kn-zeile-h); padding: 0 4px; transition: transform 550ms var(--kn-bremse), visibility 0s; } +.kn-rw { display: flex; align-items: center; height: var(--kn-zeile-h); padding: 0 max(4px, env(safe-area-inset-right)) 0 max(4px, env(safe-area-inset-left)); transition: transform 550ms var(--kn-bremse), visibility 0s; } .kn-leiste-reel[data-etage="offen"] .kn-rw { transform: translateY(-56px); } .kn-leiste-reel[data-etage="offen"] #kn-zeile-haupt, .kn-leiste-reel:not([data-etage="offen"]) #kn-zeile-etage { visibility: hidden; transition: transform 550ms var(--kn-bremse), visibility 0s 550ms; } diff --git a/public/neu/oeffentlich/oeffentlich.css b/public/neu/oeffentlich/oeffentlich.css index 6f0dc01..05ddd96 100644 --- a/public/neu/oeffentlich/oeffentlich.css +++ b/public/neu/oeffentlich/oeffentlich.css @@ -14,10 +14,10 @@ /* ------------------------------------------------------------------ Anmeldung --- */ .kn-login-seite { min-height: 100svh; } -.kn-login-kopf { position: fixed; top: 0; left: 0; right: 0; z-index: 2; padding: calc(24px + env(safe-area-inset-top)) 24px 16px; pointer-events: none; } +.kn-login-kopf { position: fixed; top: 0; left: 0; right: 0; z-index: 2; padding: calc(24px + env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) 16px max(24px, env(safe-area-inset-left)); pointer-events: none; } .kn-login-logo { pointer-events: auto; font-size: 18px; line-height: 24px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; } .kn-seite a.kn-login-logo { text-decoration: none; } -.kn-login-haupt { min-height: 100svh; display: flex; align-items: center; justify-content: center; padding: calc(88px + env(safe-area-inset-top)) 24px calc(40px + env(safe-area-inset-bottom)); } +.kn-login-haupt { min-height: 100svh; display: flex; align-items: center; justify-content: center; padding: calc(88px + env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) calc(40px + env(safe-area-inset-bottom)) max(24px, env(safe-area-inset-left)); } .kn-login-spalte { width: 100%; max-width: 360px; } .kn-login-marke { display: none; } .kn-login-titel { margin: 0 0 24px; font-size: 22px; line-height: 28px; font-weight: 700; letter-spacing: -.02em; } @@ -50,7 +50,7 @@ } /* ------------------------------------------------------------------ Kündigen und Widerrufen (schlicht) --- */ -.kn-recht main { max-width: 620px; margin: 0 auto; padding: 48px 20px 80px; } +.kn-recht main { max-width: 620px; margin: 0 auto; padding: 48px max(20px, env(safe-area-inset-right)) 80px max(20px, env(safe-area-inset-left)); } .kn-recht h1 { margin: 0 0 8px; font-size: 28px; line-height: 34px; font-weight: 700; letter-spacing: -.02em; } .kn-recht h2 { margin: 0 0 12px; font-size: 18px; line-height: 26px; font-weight: 600; } .kn-markenzeile { margin-bottom: 8px; font-size: 13px; font-weight: 700; letter-spacing: .12em; color: var(--kn-text-2); } @@ -140,7 +140,7 @@ body.ab-seite { font: 16px/1.55 var(--kn-font); -webkit-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; } .ab-seite .hidden { display: none !important; } -.ab-seite .ab-innen { max-width: 40rem; margin: 0 auto; padding: 0 16px; box-sizing: border-box; width: 100%; } +.ab-seite .ab-innen { max-width: 40rem; margin: 0 auto; padding: 0 max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); box-sizing: border-box; width: 100%; } .ab-seite .ab-kopf { padding: max(20px, env(safe-area-inset-top)) 0 12px; } .ab-seite .ab-kopf .ab-innen { display: flex; align-items: center; gap: 10px; } .ab-seite .ab-logo { width: 36px; height: 36px; border-radius: 6px; display: block; } @@ -234,7 +234,7 @@ body.ab-seite { .ab-app-back { display: none; } @media (display-mode: standalone) { .ab-app-back { - display: inline-block; margin: calc(env(safe-area-inset-top) + 12px) 16px 0; font-size: 15px; font-weight: 600; color: var(--ab-text); text-decoration: none; + display: inline-block; margin: calc(env(safe-area-inset-top) + 12px) max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left)); font-size: 15px; font-weight: 600; color: var(--ab-text); text-decoration: none; } .ab-seite .ab-kopf { padding-top: 12px; } } diff --git a/public/neu/oeffentlich/offline.html b/public/neu/oeffentlich/offline.html index 220fa8b..664f74b 100644 --- a/public/neu/oeffentlich/offline.html +++ b/public/neu/oeffentlich/offline.html @@ -9,7 +9,7 @@