The unconditional max-width:640px override collided with Klaro's own
breakpoint-dependent centering (margin:auto only applies above an
internal JS-set breakpoint; below it the modal is fixed/width:100%
with no left/margin, so the wider modal rendered flush-left instead
of centered). Explicit left:50%+translate(-50%,-50%) centers on both
axes regardless of which of Klaro's own branches is active.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real bugs, both confirmed via screenshot 2026-08-02:
- dark3 was set to a near-white cream tone assuming background-only
use, but Klaro's .cm-list-description rule uses it as a TEXT color
— every service description was almost invisible. Changed to
--color-text-muted.
- The service.disableAll.description="" override to hide Klaro's
boilerplate toggle-all text broke its own t() lookup, rendering a
literal "[missing translation: de/service/disableAll/description]"
string instead — worse than the original. Reverted, hidden via a
plain CSS display:none on .cm-toggle-all .cm-list-description
instead.
Also a real redesign pass on the settings modal's service/purpose
list (wider modal, row separators, bigger/clearer toggle switches,
distinct footer) — was previously only reachable via the notice's own
generic styling, still visibly "default library layout" per Marco's
own read.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Empties Klaro's own "Mit diesem Schalter..." boilerplate under the
modal's per-service toggle-all switch — redundant next to a plainly
labeled switch.
- .cn-ok/.cn-buttons/.cm-buttons now explicit flex-wrap rows (side by
side until they genuinely don't fit, then wrap) instead of relying
on Klaro's own fragile inline-block flow.
- Every tracking-codes provider gets a real description in the modal's
service list (was title-only) — what it does and, where publicly
documented and stable, the actual cookie names/lifetimes (_ga/
_ga_<container-id> for GA4, _fbp/fr for Facebook Pixel). GTM/Maps
descriptions are deliberately non-specific about exact cookies —
neither has a fixed, publicly enumerable list.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Uses Klaro's own built-in contextual-consent mechanism (not
loadTrackingCode.ts's script-injection path) — the iframe renders
with data-name="google-maps" and its real src; Klaro's DOM scan finds
it after mount and blanks/restores src based on that service's
consent state, showing its own placeholder (styled via
KlaroConsentManager.tsx's KlaroTheme) in the meantime.
No map embedded anywhere in the app yet — this is prep work only, per
explicit request ahead of an actual page needing one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ProductGallery.tsx (main image + thumbnail strip) wired into
TodoKartenHero.tsx, only replacing the static hero photo once a
product actually has extra gallery photos — no visual change
otherwise. Backend field: Products.gallery (see payload repo).
Klaro's hard black border was still showing after the previous
color-only pass — the targeted border:none rule wasn't enough, so
this blanket-resets border/outline on every .klaro descendant and
re-adds only the shadow this theme actually wants. Also disables the
"Realisiert mit Klaro!" attribution link (BSD-3-Clause has no
on-page-attribution requirement, Klaro's own disablePoweredBy flag
covers this cleanly).
Updates the frontend README with the gallery + Klaro fixes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CSS-var overrides alone (colors, corner position) still left Klaro's
own border/shadow/spacing/typography, which read as an obviously
bolted-on library widget next to this site's hand-designed
components. New KlaroTheme component overrides Klaro's real DOM
classnames directly (confirmed against kiprotect/klaro's own scss
source) — kills the default border, adds this site's own soft-shadow
card look, restyles every button, uses the site's actual serif/sans
font pairing. Also warms up the notice/modal copy.
Updates both READMEs with the tracking-codes/Klaro/back-in-stock/
settings-search/DHL-shipment-label work from this session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Was full-width ('wide' theme) with Klaro's default green/dark
palette, neither matching the brand. Now: compact bottom-left corner
notice (~380px), brand colors via Klaro's CSS-var overrides
(dark1/light1 etc. — confusingly named, they're background/text, not
a dark-mode switch), neutral gray decline button instead of red.
Also adds a persistent bottom-left cookie icon (KlaroConsentManager.tsx)
so a visitor can reopen the consent manager any time via Klaro.show(),
not just on first visit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Swaps the hand-rolled CookieBanner.tsx/useConsent.ts/TrackingScripts.tsx
for kiprotect/klaro — brings a real per-service consent list and
bundled German UI translations that a custom implementation would
have had to build from scratch (per user feedback that a proper CMP
is worth it over a purely custom binary accept/reject banner).
klaroConfig.ts builds Klaro's config dynamically from the existing
tracking-codes backend collection (one Klaro "service" per row,
grouped by consentCategory as its purpose). loadTrackingCode.ts is
the actual script-injection side effect, wired in via each service's
`callback(consent)` — same GA4/Facebook-Pixel/GTM/custom loader logic
TrackingScripts.tsx had, just triggered imperatively instead of
declaratively rendered. Brand color applied via Klaro's CSS custom
property overrides (styling.green1 etc.), not custom SCSS.
No @types/klaro package exists — types/klaro.d.ts declares only the
small surface actually used.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>