From 23f8efcc2b585efc172c5ee4a69c4680d06c20e7 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 1 Aug 2026 22:20:16 +0000 Subject: [PATCH] Fix Klaro backdrop only covering a column, not full viewport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: .cookie-modal is the full-viewport wrapper, NOT the dialog box — the previous centering fix wrongly applied position/transform to it. Adding a transform to that wrapper created a new containing block for its position:fixed children, so .cm-bg (the backdrop) started positioning itself relative to the now- shrunken/centered wrapper instead of the real viewport — the dark overlay only covered a 640px-wide column (screenshot-confirmed 2026-08-02) instead of the whole screen. Moved all sizing/position/shadow overrides to .cm-modal.cm-klaro (the actual dialog box, a sibling of .cm-bg — both children of the untouched full-screen .cookie-modal). Also fixed several selectors that were quietly matching nothing: .cn-body doesn't exist in the settings modal (that's .cm-header/.cm-body), and the footer button row is .cm-footer-buttons, not .cm-buttons (that class belongs to the small notice/context-notice components only). Restyled the modal's close button and structural padding to match, now that the real selectors are confirmed against klaro's own consent-modal.jsx source. Co-Authored-By: Claude Sonnet 5 --- app/components/KlaroConsentManager.tsx | 90 +++++++++++++++++++------- 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/app/components/KlaroConsentManager.tsx b/app/components/KlaroConsentManager.tsx index c1058f1..cf91b29 100644 --- a/app/components/KlaroConsentManager.tsx +++ b/app/components/KlaroConsentManager.tsx @@ -48,15 +48,19 @@ function KlaroTheme() { /* Matches NewsletterModal.tsx's own backdrop color (bg-[rgba(134,134,134,0.9)]) instead of Klaro's default plain black at 50% — same dimming purpose, but consistent with how - every other modal on this site already looks. */ + every other modal on this site already looks. .cm-bg is a + *sibling* of the actual dialog box (.cm-modal.cm-klaro), both + direct children of the full-screen .cookie-modal wrapper — see + that wrapper's own comment below on why it must never be resized/ + transformed itself. */ .klaro .cm-bg { background: rgba(134, 134, 134, 0.9) !important; } - .klaro .cookie-notice, .klaro .cookie-modal { + .klaro .cookie-notice, .klaro .cm-modal.cm-klaro { box-shadow: 0 20px 44px -14px rgba(26,26,24,0.22), 0 4px 14px rgba(26,26,24,0.07) !important; border-radius: 18px !important; font-family: var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important; } .klaro .cookie-notice .cn-body { padding: 22px 24px !important; } - .klaro .cookie-notice p, .klaro .cookie-modal p { + .klaro .cookie-notice p, .klaro .cm-modal.cm-klaro p { font-size: 14px !important; line-height: 1.6 !important; margin-top: 0 !important; @@ -127,30 +131,62 @@ function KlaroTheme() { /* ---- Settings modal service/purpose list — a real pass modeled on well-known CMPs like Cookiebot (roomier modal, clear row separators, bigger switches, muted-but-legible descriptions), - not just inherited from the notice's own styling. Class names - confirmed against node_modules/klaro's src/scss/switch.scss + - klaro.scss, not guessed. */ - /* Explicit centering on both axes, not Klaro's own margin:auto — - that only applies above Klaro's internal (JS-set, not a CSS var - this theme controls) centerWidth breakpoint; below it the modal - is position:fixed/width:100% with no left/margin at all, so an - unconditional max-width override (needed for the wider 640px - modal below) left it flush against the left edge instead of - centered — confirmed via screenshot 2026-08-02. left:50% + - translate(-50%,-50%) centers correctly at every viewport size - regardless of which of Klaro's own breakpoint branches is active. */ - .klaro .cookie-modal { + not just inherited from the notice's own styling. + + DOM structure (confirmed against kiprotect/klaro's own + src/components/consent-modal.jsx — the FIRST version of this + pass guessed wrong and broke the backdrop, see the incident note + below): + .cookie-modal full-viewport wrapper (position: + fixed, 100%×100%) — MUST stay + untouched; giving it its own + transform/position (tried first) + creates a new containing block + for its position:fixed children, + so .cm-bg below started + positioning itself relative to + THIS shrunken/centered box + instead of the real viewport — + the backdrop only covered a + 640px-wide column, screenshot- + confirmed 2026-08-02. + .cm-bg the dark backdrop (styled above) + .cm-modal.cm-klaro the actual dialog box — every + size/position override belongs + HERE, not on .cookie-modal. + .cm-header close (×) + h1.title + intro

+ .cm-body the service/purpose list + .cm-footer > .cm-footer-buttons decline/accept/accept-all + row (NOT .cm-buttons — that + class belongs to the small + notice/context-notice components + only, an earlier pass wrongly + reused it here too and the rule + silently matched nothing). */ + .klaro .cm-modal.cm-klaro { position: fixed !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; width: calc(100% - 40px) !important; max-width: 640px !important; + max-height: 88vh !important; + overflow: auto !important; margin: 0 !important; } - .klaro .cookie-modal .cn-body { padding: 32px 36px !important; } - .klaro .cookie-modal h1 { font-size: 26px !important; margin-bottom: 4px !important; } - .klaro .cookie-modal > .cn-body > p:first-of-type { color: #6b6b69 !important; margin-bottom: 24px !important; } + .klaro .cm-header { padding: 32px 36px 0 !important; } + .klaro .cm-body { padding: 8px 36px !important; } + .klaro .cm-footer { padding: 0 36px 32px !important; } + .klaro .cm-header h1.title { font-size: 26px !important; margin-bottom: 4px !important; } + .klaro .cm-header > p { color: #6b6b69 !important; margin-bottom: 0 !important; } + .klaro .cm-header .hide { + position: absolute !important; + top: 28px !important; + right: 28px !important; + color: #6b6b69 !important; + font-size: 20px !important; + } + .klaro .cm-header .hide:hover { color: #1a1a18 !important; } /* Re-adds a deliberate row separator the blanket border-reset above removes — each purpose/service row genuinely benefits from one, @@ -175,13 +211,21 @@ function KlaroTheme() { .klaro .cm-caret { color: #6b6b69 !important; } - /* Bottom action row reads as a distinct footer, not just the last - list item — separated + slightly recessed. */ - .klaro .cookie-modal .cm-buttons { + /* Bottom action row (decline/accept/accept-all) — real classname + is .cm-footer-buttons here, NOT .cm-buttons (see the DOM- + structure note above); reads as a distinct footer, not just the + last list item — separated + given the same side-by-side/wrap + treatment as the notice's own buttons. */ + .klaro .cm-footer-buttons { + display: flex !important; + flex-wrap: wrap !important; + gap: 10px !important; border-top: 1px solid #e5e0d8 !important; - margin-top: 24px !important; + margin-top: 16px !important; padding-top: 20px !important; } + .klaro .cm-footer-buttons .cm-btn { width: auto !important; margin: 0 !important; } + .klaro .cm-powered-by { display: none !important; } /* Hides the "alle umschalten" toggle's own boilerplate description ("Mit diesem Schalter können Sie alle Dienste aktivieren oder