Das kostenlose WordPress-Theme aus Deutschland


New

Gradients in every color picker

The regular Customizer color picker (Customize_Circular_Color_Control) now lists the four base gradients (Colors → „Base gradient 1–4“) as swatches right behind the 12 base colors — same grid, same active ring, same click. A color setting therefore holds either a color or a CSS gradient string.

  • 18 gradient-capable settings: header, extra header, mobile menu, content and footer backgrounds; header buttons + hover; content buttons + hover; H1–H6; content links + hover; free-shipping bar fill. In every other color picker the gradient swatches stay visible but disabled, with a tooltip explaining why (text, border and icon colors cannot render a gradient).
  • The separate „Headings gradient“, „Links gradient“ and „Button background gradient (+ hover)“ fields are gone. Stored values are migrated once into the respective color settings (webseide_migrate_gradient_mods, headings → H1–H6).
  • Gradient editor (Colors): Solid / Linear / Radial. Linear with angle slider + exact number (0–360°); radial with 9 positions and a radius of 10–200 % (slider + number). An empty slot shows its palette-based default with a „Default“ badge; „Reset to default“ empties the slot again.
  • Defaults for empty slots (webseide_gradient_default() / webseide_base_gradient()): slot 1 = base color 3 → 4, slot 2 = 2 → 3, slot 3 = 4 → 5, slot 4 = radial grey 8 → 7. All consumers read through these helpers: picker swatches, :root { --wsg1..4 }, the .has-wsgN-* block classes, block-editor gradient presets and palette, Elementor variables.
  • Frontend output via webseide_css_bg() / webseide_css_text() in inc/customizer-css.php: backgrounds become background-image + transparent color; headings and links get a text-clipped gradient with the first color stop as fallback (underlines, icons); hover states on top of a gradient base reset cleanly; places that use a color for borders, shadows or icons get the first color stop. Live preview (js/customizer.js), editor styles, design sync, maintenance page and login branding use the same helpers. For solid colors the generated CSS is byte-identical to 3.2.1.

Live palette and „Update existing colors site-wide“

  • Changing a base color or base gradient repaints that swatch instantly in all 37 pickers (gradient ⇄ solid included). Empty gradient slots recompute their default from the current base colors; the gradient editor refreshes its defaults and badge. No reload needed.
  • A picked swatch stores a copy of the slot value. Which setting follows which slot is now remembered in the hidden setting webseide_color_refs; settings whose value equals a slot value when the Customizer loads are linked implicitly, so existing sites work too.
  • New button „Update existing colors site-wide“ at the end of the Colors section writes the current base colors and gradients into every linked setting, reports how many changed, and leaves the result in the changeset — review the preview, then publish. Setting a linked field to a custom color unlinks it.

Mini-cart icon links to the cart page

The WooCommerce Mini-Cart block never renders a link: a button opens the drawer, and on cart/checkout it is a disabled, hidden button. A render filter (render_block_woocommerce/mini-cart) rewrites the button into <a class="wc-block-mini-cart__button" href="…/cart/"> and removes disabled, visibility:hidden and aria-hidden on cart and checkout; a capture-phase click handler keeps the drawer behaviour: items in the cart + drawer available → the drawer opens as before; empty cart, cart/checkout pages or Cmd/Ctrl/Shift-click → the link is followed. Right-click „open in new tab“ works.

Header icon line thickness

New setting under Customizer → WooCommerce → Mini-Cart: „Header icon line thickness“ (0.5–3 px, default 1 px) sets the stroke-width of all SVG header icons (search, wishlist, mini-cart, hamburger).

Maintenance page

  • Uses the theme’s own background, text and link colors and font by default. The prefers-color-scheme: dark auto-switch is replaced by an explicit „Use dark palette on the maintenance page“ toggle (off by default).
  • Logo fallback chain: alternative logo → theme logo → WordPress custom logo → site name.
  • New contact links Phone (tel:) and WhatsApp (https://wa.me/), the number shows as tooltip. Icon order: email, phone, WhatsApp, Facebook, Instagram, YouTube, LinkedIn, X, TikTok.
  • Imprint and privacy page always expand inline as <details> toggles (the two „expand content“ checkboxes are gone); the expanded content floats below the footer row, so the links no longer wrap. The privacy page defaults to the page configured under Settings → Privacy.
  • The Google Fonts of the four Customizer font settings are loaded (preconnect + stylesheet); @font-face rules of an active child theme are injected with absolute URLs.
  • New toggle „Load full theme + child theme CSS on the maintenance page“ (on by default): parent style.css, child style.css and the Customizer CSS are frozen into the static files, so the page matches the live design; the maintenance-specific inline styles still win.

Changes

  • Customizer preview now refreshes for every setting. 137 settings (113 in inc/customizer.php, 23 in the WooCommerce module, 1 in the menu module) were registered with postMessage without any preview handler, so nothing happened until save. They use refresh now. The rule is documented at the top of webseide_customize_register(): handler in js/customizer.js → postMessage, otherwise refresh.
  • Live preview handlers fixed and completed: mobile menu background and font listened to setting IDs that never existed; H5, H6, link hover and button background hover had no handler (hover states go into a preview stylesheet). Handlers for non-existent settings removed. customizer.js is versioned by file time so browsers never keep an old copy.
  • Base color defaults live in one place (webseide_base_color_defaults()); the swatch of base color 9 showed #474748 while setting and CSS use #727272.
  • Base gradient settings default to empty instead of the computed string: untouched slots are never saved just because the Customizer was opened, and the „Default“ badge shows again.
  • Dead trigger_change code in the alpha color picker removed (including a stray quote in the input markup).
  • Free-shipping bar: calmer wording (no emoji, no bold); in the cart/checkout totals cell only bar and info line are injected — the „Shipping | amount“ row stays in the mini-cart, where it is the only shipping information. The obsolete option „Also show the free-shipping bar on the cart page“ (a second, PHP-rendered bar) is removed. Script version 1.2.0.

Fixes

WooCommerce / Germanized Pro

  • Legal price info (tax and shipping note) moves below the price next to the add-to-cart button. The Germanized callback is detached by scanning the registered shopmark callbacks at their real priority — no template override, survives Germanized updates, works for variable products.
  • Multistep checkout: nav-wizard links use the Customizer link colors (the active step keeps the button colors); the returning-customer login prompt is hidden from the payment step on; the payment step is ordered payment methods → review table → legal checkboxes → submit button; the confirm step (#order-verify) is ordered heading → data check → table → checkboxes → button, its totals rows render as label/value rows, the review table gets margin-bottom: 2em, and the shipping bar is not repeated there.
  • Cart: German translation of the free-shipping sentence (the <strong> variant was untranslated); the totals block loses its 2 rem left inset; the „create account“ checkbox gets the same box-to-text distance as the shipping-address row (16 px); #ship-to-different-address inherits the font family.
  • Header icons: WooCommerce’s filled cart SVG and its duplicate ::before glyph are hidden; the theme draws its own stroked 20 px cart icon via a mask on the quantity-badge wrapper, matching the wishlist and search icons, and the count badge becomes a grey pill with black text at the top right like the wishlist counter. Search, wishlist and mini-cart sit on one baseline at all breakpoints — flex alignment with consistent gaps replaces the old line-height / translateY compensation. Selectors are specific enough to beat child-theme overrides. Mini-cart drawer: title reduced to 20 px, the „(items: X)“ counter hidden, drawer icons use the same stroke width.

Theme

  • .main-navigation.toggled emitted invalid CSS (background-color: background-color: …); it now uses the header background, color or gradient.
  • SVG logos: #logo { height: …; width: auto; max-width: none } — logos collapsed to 0 px width in some layouts.
  • Editor styles: dead rule removed; H1–H6, links and buttons are gradient-aware like the frontend.

Internationalization

35 new strings, de_DE (du) and de_DE_formal (Sie) fully translated, .mo recompiled. Other languages unchanged (English fallback).


File manifest (3.2.2 vs 3.2.1)

assets/js/free-shipping-bar.js                                  (row only in the mini-cart, calmer wording)
functions.php                                                   (block-editor gradient presets via webseide_base_gradient())
inc/css/style-editor.php                                        (gradient-aware editor CSS)
inc/customizer-css.php                                          (gradient helpers, palette defaults, refs sanitizer, WC/Germanized CSS, cache key)
inc/customizer.php                                              (gradient controls, color refs + button, transport audit, migration)
inc/customizer/alpha-color-picker/*                             (dead trigger_change removed)
inc/customizer/circular-color-picker/*                          (gradient swatches, live palette, refs, update button)
inc/customizer/customize-control/class-customize-control.php    (button control type)
inc/customizer/gradient-color/class-gradient-color-control.php  (linear angle, radial position/radius, live defaults)
inc/design-sync.php, inc/modules/elementor/module.php,
inc/modules/backend_admin_functions/module.php                  (gradient-aware: first color stop / background helper)
inc/maintenance.php                                             (theme styles, dark toggle, phone/WhatsApp, fonts, theme CSS)
inc/modules/menu_toggle/module.php                              (transport)
inc/modules/woocommerce_functions/module.php                    (mini-cart link, icon thickness, legal info hook, transport, shipping bar)
js/customizer.js                                                (preview handlers)
languages/de_DE.po/.mo, languages/de_DE_formal.po/.mo, readme.txt, style.css

Upgrade notes

  • CSS cache key bumped (v21 → v45, one step per build iteration); the transient regenerates on the first frontend request. Clear WP Rocket’s Used-CSS cache once after the upgrade.
  • Stored „Headings / Links / Button gradient“ values are migrated into the color settings automatically on the first request after the update.
  • The four base gradients now also appear as block-editor presets and as var(--wsg1..4) even when no gradient has been configured (palette-based defaults).
  • Mini-cart icon: sites using the WooCommerce Mini-Cart block get a real link; the drawer behaviour is unchanged. With WP Rocket „Delay JavaScript“ the small inline handler is delayed like the existing badge script; until it runs, a click simply follows the link.
  • Maintenance page: „Load full theme + child theme CSS“ is on by default — save the Customizer once so the static files are regenerated.
  • No breaking changes.

Release date: 21.10.2026
Patch release on top of 3.2.0.


New

Design synchronisation (new module inc/design-sync.php)

Customizer section „Design synchronisation“ at the bottom of the basic settings (priority 198, just before Additional CSS). Only visible when Kadence Blocks and/or Elementor are active — no clutter on sites without them.

Push buttons (manual, in the section description):

  • → Push to Kadence Blocks now — writes mapped Customizer colors into the kadence_blocks_global_palette option:
    • palette1 ← webseide_color_content_links
    • palette2 ← webseide_color_content_buttons_background
    • palette3 ← webseide_color_content_text
    • palette4 ← webseide_color_content_background
    • palette5 ← webseide_color_content_buttons_font
    • Slots 6–9 are untouched (Kadence’s own extended palette survives).
    • First push snapshots the existing palette into webseide_sync_snapshot_kadence. A restore link appears next to the push button so the pre-push state can be returned at any time.
  • → Push to Elementor now — writes into the active Kit’s _elementor_page_settings meta:
    • system_colors primary / secondary / text / accent (update-in-place by _id).
    • button_background_color, button_text_color.
    • button_border_radius (from webseide_input_borderradius, px, linked).
    • system_typography primary (heading) / secondary (body) typography_font_family (strips Google-Font weight suffix after :).
    • First push snapshots the existing kit into webseide_sync_snapshot_elementor with the same restore workflow.
    • Elementor CSS cache (\Elementor\Plugin::$instance->files_manager->clear_cache()) is cleared after the push so the next page load regenerates.

Opt-out toggles (plugin-aware; appear only when that plugin is active):

  • Disable theme styles for Kadence Blocks — adds body class webseide-no-kadence-overrides + injects an all: revert reset at wp_head priority 999 on the main Kadence containers (.wp-block-kadence-rowlayout, .wp-block-kadence-column, .wp-block-kadence-pane, .wp-block-kadence-modal, .kb-row-layout-wrap, .kt-row-layout-inner, .kt-row-column-wrap, .kt-inside-inner-col, .kt-tabs-wrap, .kadence-blocks-form-field, .kb-form .kb-forms-submit). Kadence Style Library owns the design alone.
  • Disable theme styles for Elementor — the Elementor integration module skips its stylesheet enqueue + the --webseide-color-* / --e-global-color-webseide-* CSS-variable output + the Google-fonts-skip filter. Title-tag suppression stays active (unrelated to design).

Push is one-way. No pull from plugin back to theme — avoids race conditions, infinite loops, ambiguous reverse mapping. Direct changes in Kadence/Elementor UI will be overwritten on the next push from the theme.

Maintenance page: widget area + privacy toggle

  • New sidebar „Maintenance page widgets“ registered on widgets_init. Rendered between the message and the social icons. Captured at customize_save_after via ob_start() + dynamic_sidebar() and frozen into both the static wp-content/maintenance.php and the Plesk maintenance_page/index.html. Only widgets producing self-contained HTML (no AJAX, no DB queries) will work during a core/DB outage; AJAX widgets work in manual mode where WP is up.
  • New Customizer settings:
    • Privacy policy page (dropdown-pages)
    • Expand privacy content from the footer link (checkbox)
  • Footer renders imprint + privacy together as flex row with · separator. Each is either a <details> toggle (if its „expand inline“ setting is on and the page has content) or a regular <a> link.
  • Fallback: if neither imprint nor privacy is configured, the site name is shown as before.

Fixes

Bestellhinweise textarea fill

WooCommerce 11+ introduced .woocommerce form .form-row .input-text with --wc-form-color-background (defaults to #fff). That selector has specificity (0,0,3,1) and was beating the theme’s bare textarea rule (0,0,0,1), leaving the textarea white instead of the Customizer form color.

Fix in inc/customizer-css.php:

.woocommerce,
.woocommerce-page,
.woocommerce-checkout,
.woocommerce-cart,
.woocommerce-account {
    --wc-form-color-background: <customizer form color>;
    --wc-form-color-text: <customizer form text>;
    --wc-form-color-border: transparent;
}
/* Hard ID override as belt-and-suspenders */
html body textarea#order_comments,
html body .woocommerce form .form-row textarea.input-text,
html body .woocommerce form .form-row input.input-text,
html body .woocommerce-checkout textarea,
html body .woocommerce-additional-fields textarea {
    background-color: <customizer form color>;
    color: <customizer form text>;
}

Review-order table — three columns

woocommerce/checkout/review-order.php template override. WC default puts the product name + × N quantity into one cell (.product-name), which gets clipped in the narrow right column of the modern checkout. New structure:

ProduktAnzahlSumme
Product name + variations + metadata× Nsubtotal
  • woocommerce_checkout_cart_item_quantity filter is set to __return_empty_string for the duration of the template so WC doesn’t duplicate the quantity into the name cell. Removed after the template renders.
  • Footer rows (subtotal, coupons, shipping, fees, tax, order total) get colspan="2" on the value cell so the three-column structure stays consistent.
  • Header: „Summe“ instead of „Zwischensumme“ (shorter for the narrow column).
  • @version 11.2.0 header set so WooCommerce → Status → Templates shows green instead of the „Versions-Header fehlt“ warning.

Form error color mapping

webseide_forms_error_color now applied globally to WooCommerce + Germanized error states:

.woocommerce-error, ul.woocommerce-error,
.woocommerce-invalid > label,
.woocommerce-invalid input.input-text,
.woocommerce-invalid select, .woocommerce-invalid textarea,
.woocommerce-invalid .select2-selection,
#legal_description, .wc-gzd-additional-info-notice {
    border-color: <error color>;
}
.woocommerce-error::before, ul.woocommerce-error::before {
    color: <error color>;
}

Payment-methods layout

  • ul.wc_payment_methods + ul.payment_methods padding: 0 (removes WC default indent)
  • Radios 18 px matching theme radio size
  • Labels flex: 1 1 0; min-width: 0; overflow: hidden + payment-logo images max-width: 100%; flex-shrink: 1 → logos shrink instead of clipping out of the right column
  • Payment-box background changed from WC-default pink to neutral grey #f5f5f5

Button unification

  • „Warenkorb aktualisieren“, „Weiter zur Kasse“, „Jetzt kaufen“ all share font-size (1 rem) + padding (0.9rem 1.5rem) + line-height
  • Primary action buttons right-aligned (.wc-proceed-to-checkout, .form-row.place-order, .wc-gzd-order-submit); margin-right: 0

Minor

  • #ship-to-different-address H3 neutralized to look like a regular checkbox row (font-size + weight + line-height inherit)
  • 50 px margin-bottom on cart + checkout content areas for footer breathing room
  • Modern-checkout CSS: @version cache bust uses parent-theme version via wp_get_theme( get_template() )->get('Version') instead of active-theme version (which on child-theme sites was the child’s version, not webseide’s)
  • Payment radios no longer get an appearance: auto override — fall through to the global theme radio style

Consolidates all 3.1.9.x patch iterations into one final release.


New features

Maintenance page module (inc/maintenance.php)

Full-featured branded maintenance page, generated as a static HTML file and used in three contexts:

  • Automatic during WP updates — written to wp-content/maintenance.php, picked up automatically by WP core during plugin/theme/core updates.
  • Automatic via Plesk — written to <webroot>/../maintenance_page/index.html so Plesk’s „Suspend domain“ serves it. Custom path override field for non-Plesk setups; admin notice if the auto-detected path is not writable.
  • Manual activation — Customizer checkbox serves the page via template_redirect (503 + Retry-After + nocache), with audience selector (Guests only / Guests + subscribers / Everyone except admins). /wp-admin and wp-login.php always stay reachable.

Customizer section (at the bottom of the section list, before Additional CSS):

  • Alternative logo override (uses main Custom Logo if blank).
  • Message (wp_kses_post).
  • 7 contact links: Email (mailto) + Facebook, Instagram, YouTube, LinkedIn, X, TikTok — all with inline SVG icons.
  • Imprint page dropdown + „expand inline from the footer link“ toggle (renders page content inside a <details> element in the footer).
  • „Allow search engines to crawl during maintenance“ toggle (200 + index/follow instead of 503 + noindex).
  • Custom static-page path override.
  • Preview link → opens ?preview_webseide_maintenance=1 in a new tab, admin-only (200 OK for easy testing).

Design: self-contained HTML, inline CSS, inline SVG icons, system font stack, no external resources — works even when the database is down.

Modern Cart & Checkout layout (inc/modern-checkout.php)

Opt-in two-column layout via Customizer → WooCommerce → Checkout → Cart & Checkout layout = Modern (default: Classic — no change for existing stores).

  • Grid-based layout on 901px+: billing + shipping + additional fields left (#customer_details), order review + coupon + payment right (#order_review).
  • Cart page keeps the full site header; Checkout gets an optional minimal logo bar (toggle).
  • Minimal Checkout header uses the theme’s own Header-background and Header-font color (Customizer-driven), with:
    • Logo (via webseide_get_logo() or WP native fallback) linking to home.
    • Right side configurable: cart link with item count / Header-Right widget area / nothing.
  • New widget area „Checkout header (right)“ for drop-in cart widgets, trust badges, phone number, etc.
  • Login toggle above billing fields (opt-in).
  • URL override: ?checkout_layout=modern and ?checkout_layout=classic work on any cart/checkout URL for live preview without flipping the setting.
  • Zero visual theming inside the module — colors, fonts, buttons all come from the Customizer. Only structural CSS (grid, hide-site-chrome in min-header mode).

LCP priority hints for featured images (inc/lcp-featured.php)

webseide renders featured images as CSS background-image on .fullthumbnail, so neither fetchpriority nor loading="eager" applies. Instead, the module emits <link rel="preload" as="image"> hints in <head> for the above-the-fold featured image:

  • Singular posts/pages: the queried object’s featured image at the exact hero size.
  • Archive views (home, category, tag, author, date, search): the first post’s featured image.
  • Custom logo gets fetchpriority="high" via get_custom_logo filter.
  • First <img> thumbnail in archive loops (sticky posts, image post format) gets loading="eager" + fetchpriority="high".
  • imagesrcset + imagesizes for responsive variant selection.

Form field normalization (global, across cart/checkout/comments/widgets/Gravity Forms/CF7/Germanized)

Checkboxes & radios

  • Fixed 18 × 18 pixels everywhere — strict pixel values, no em/rem/min/max — so parent font-size never shifts the box.
  • Theme-aligned appearance: transparent border, filled background from webseide_forms_color, filled color change on :checked using webseide_color_content_buttons_background.
  • Checkmark + radio dot rendered as inline SVG backgrounds (white) — crisp at any size.
  • Checkboxes square (border-radius 2px, configurable), radios circular.
  • Legacy padding/.5em + ::before checkmark overlays removed from style.css.
  • Specificity via html body prefix; !important only on padding and margin where WC inline styles would otherwise win.

Border-radius setting (new)

Customizer → Buttons & Formulare → „Border radius for checkboxes“ (0–N px, default 2). Radios stay circular regardless.

Selects

  • Theme’s custom SVG chevron on select + .select2-container--default .select2-selection--single removed.
  • Native browser chevron restored on <select> via appearance: auto.
  • Select2-wrapped selects (country/state in checkout) show Select2’s own .select2-selection__arrow CSS triangle — no doubling.
  • Gravity Forms appearance: none override removed too.

Form error color

webseide_forms_error_color is now mapped to WooCommerce + Germanized error states globally:

  • .woocommerce-error border-top and ::before icon color.
  • .woocommerce-invalid field borders (input/select/textarea/.select2-selection).
  • #legal_description border.
  • Germanized .wc-gzd-additional-info-notice.

WC form variables

WooCommerce 11+ --wc-form-color-background + --wc-form-color-text + --wc-form-color-border now remapped to the theme’s form colors (Customizer-driven), so .input-text + #order_comments textarea pick up the theme fill automatically.


WooCommerce checkout + cart refinements

Cart

  • Mobile (<768px): table collapses to a grid-per-item layout — thumbnail + name + × remove in top row, price/qty/subtotal underneath.
  • „Warenkorb aktualisieren“ button never full-width on mobile.
  • 2rem padding-left on .cart-collaterals side-by-side (768+) for breathing room.
  • „Warenkorb-Summe“ <h2> hidden in modern mode (summary speaks for itself).

Checkout

  • Grid in modern mode: #customer_details { grid-column: 1; grid-row: 1 }, #order_review { grid-column: 2; grid-row: 1 / span 2; min-width: 0 }.
  • .col2-set { display: block } prevents site-wide .col2-set grid rules from splitting the left column.
  • .col-1 + .col-2 stack vertically inside .col2-set (float: none, width: 100%).
  • Buttons unified: „Warenkorb aktualisieren“, „Weiter zur Kasse“, „Jetzt kaufen“ all 1rem font + 0.9rem × 1.5rem padding + line-height 1.3.
  • Primary action buttons right-aligned (margin-right: 0).
  • .woocommerce-checkout-review-order-table { width: 100% !important; table-layout: fixed } — no overflow in the right column.
  • Empty PayPal Standard container (#paypal-standard-container:empty) hidden.
  • #ship-to-different-address H3 neutralized to look like a normal checkbox row (font-size + weight + line-height: inherit; margin: 0).

Payment methods

  • .wc_payment_methods + .payment_methods padding: 0 (no WC default indent).
  • Each <li> is a flex row: 18px radio + label with logo (shrinks instead of clipping) + payment-box below (flex-basis: 100%).
  • Payment-box color changed from WC-default pink to neutral grey (#f5f5f5); ::before arrow border-color matches.
  • Payment-box fieldset border/padding/margin reset.

Spacing

  • .woocommerce-cart .content-area .woocommerce + .woocommerce-checkout .content-area .woocommerce get margin-bottom: 50px.

Internationalization

  • 44 new strings across the three new modules (maintenance + modern-checkout + lcp-featured).
  • de_DE (Du) and de_DE_formal (Sie) fully translated with context-aware pronoun forms.
  • es_ES, fr_FR, it_IT, nl_NL, pl_PL, pt_BR, pt_PT: msgid-only entries added for translator pickup.
  • All .mo files recompiled via msgfmt.
  • webseide.pot template (49 KB) added to languages/ for new-language contributors.
  • Legacy broken msgstr "Fixiert\n" repaired.
  • .l10n.php cache files cleared (WP 6.5+ regenerates on first load).

Fixes

  • readme.txt stable tag was still 3.1.7 in the 3.1.8 release — corrected to track the actual version going forward.
  • Modern-checkout CSS was loading with the active (child) theme version, caching old files for sites with a child theme. Now uses wp_get_theme( get_template() )->get('Version') to always use the parent theme’s version for cache busting.
  • wp_enqueue_style + wp_head direct link duplication removed — single direct <link> injection, bulletproof against dequeue by child themes / caching plugins.
  • Chevron doubling on country select resolved (single source of truth, no double arrows).

File manifest

inc/maintenance.php          (new, ~500 LOC)
inc/modern-checkout.php      (new, ~250 LOC)
inc/lcp-featured.php         (new, ~140 LOC)
assets/css/modern-checkout.css (new, ~190 LOC)
functions.php                (3 new includes)
inc/customizer.php           (+1 Customizer setting: webseide_checkbox_borderradius)
inc/customizer-css.php       (form variable mapping, error color, checkbox fill, modern topbar BG, select chevron policy)
style.css                    (checkbox/radio normalization block, cart mobile grid, payment methods, button unification, chevron fix)
languages/                   (44 new strings in all 9 PO files; .mo recompiled; webseide.pot added)
readme.txt                   (version + changelog)

Upgrade notes

  • CSS cache key bumped from v11 → v18. Transient regenerates automatically on first frontend request.
  • WP Rocket / caching plugins: clear used-CSS cache once after upgrade — the CSS output has substantially changed.
  • Modern checkout is opt-in; defaults are Classic. No change for existing sites until the Customizer toggle is flipped.
  • Checkbox border-radius is configurable in Customizer → Buttons & Formulare (default 2 px).
  • No breaking changes. All existing settings carry over.

Editor Fixes

  • Kadence/Cover/Group Backgrounds im Editor sichtbar: Die background-color‑Property aus der verschachtelten .block-editor-block-list__layout‑Regel in inc/css/style-editor.php entfernt. Diese hatte alle Parent‑Backgrounds (Gradient, Bild, Farbe) opak übermalt. Nebeneffekt: helle Schrift auf dunklem Row‑Hintergrund war im Editor unsichtbar (weiß auf weiß) → Kontrastfehler fielen erst live auf. Outer‑Rule bleibt und liefert weiterhin die weiße Canvas.
  • Safety‑Net: zusätzlich Kadence‑gescoped background: transparent !important auf .wp-block-kadence-rowlayout/-column/.kb-row-layout-wrap/.kt-row-layout-inner/.kt-inside-inner-col‑Descendants, falls ein Plugin künftig eine ähnliche Regel injiziert.
  • .kt-tabs-wrap‑Selektor eingegrenzt: neue Regel greift nur auf .kt-tabs-content-wrap‑Listen, nicht mehr auf die Tab‑Titel‑<ul>.

Elementor‑Integration (neu)

  • Neues Modul inc/modules/elementor/ — aktiviert sich nur wenn Elementor läuft, sonst null Overhead.
  • Portiert Elementor‑spezifische Styles aus dem Standalone‑webseide-elementor‑Theme (Gravity Forms Polish, .fullheight‑Nav, Glossary CPT, Google Reviews Plugin).
  • Emittiert Theme‑Farben + Fonts als CSS‑Variablen (--webseide-color-1..12, --webseide-gradient-1..4, --webseide-font-1|2) plus Elementor‑Namespace‑Mirrors — überall in Elementor Custom‑CSS nutzbar.
  • Unterdrückt Elementors <title>‑Ausgabe (SEO‑Plugin gewinnt).
  • Skipt duplizierten Google‑Fonts‑Request wenn Theme bereits eine Base‑Font lädt.

Sicherheit

  • Fest codierter Google-Fonts-API-Schlüssel entfernt.
  • Open Redirect in template-parts/content-single.php geschlossen
    (wp_safe_redirect + esc_url_raw).
  • XSS in den Post-Meta-Daten für externe Links (content.php / content-link.php) —
    4 Websites mit esc_url() gepatcht.
  • XSS in der Hintergrund-URL des Beitrags-Thumbnails und in $caption->post_excerpt
    (Einzel- und Seitenvorlagen).
  • CSRF + WP_Query-Injektion in wp_ajax_loadmore_posts — Nonce +
    Whitelist zulässiger Abfragevariablen, orderby auf sichere Teilmenge beschränkt,
    posts_per_page aus get_option.
  • CSRF + fehlendes absint() in wp_ajax_loadmore_comments – Nonce +
    absint() bei allen Eingaben.
  • CSRF/save_post im URL-Feld des Beitragsformats „Link“ – Nonce +
    current_user_can('edit_post') + esc_url_raw().
  • CSRF/save_post bei den WooCommerce-Basispreis-Feldern
    (save_fields, save_custom_field_variations) – WC-eigenes
    woocommerce_meta_nonce + Berechtigung edit_product +
    DOING_AUTOSAVE-Prüfung.
  • CSRF beim AJAX-Handler svg_get_attachment_url_media_library —
    check_ajax_referer + Berechtigung upload_files.
  • Speichern von Metaboxen in backend_admin_settings — typabhängige Bereinigung
    (sanitize_text_field, wp_kses_post, array_map für mehrere Kontrollkästchen);
    <iframe> ist in Textarea-/Wpeditor-Feldern nicht mehr zulässig.
  • Speichern von Navigationsmenü-Einträgen — current_user_can('edit_theme_options') +
    wp_attachment_is_image()-Validierung der Bild-ID; alle $item_id–
    Ausgaben werden mit esc_attr umschlossen.
  • Social-Widget — URLs über esc_url_raw/esc_url, icon_color hex-
    validiert, html_code über wp_kses_post, title über esc_html.
  • Benutzerdefiniertes CSS pro Beitrag wird durch wp_strip_all_tags geleitet, um das
    Ausbrechen von </style><script> zu verhindern.
  • Widget woocommerce_sorting — sanitize_key() auf $_GET['orderby'].
  • Debug-Helper webseideModules()->debug() wird nur bei gesetztem WP_DEBUG aufgerufen.
  • SVG-Abmessungsfilter verwendet nun get_attached_file() (lokales Dateisystem)
    anstelle von simplexml_load_file($url) – behebt allow_url_fopen=0–
    Warnungen sowie DivisionByZeroError in webseide_get_logo().
  • Toter Code: wp_ajax_updatePostMeta-Stub in editbox.php entfernt.
  • Veraltete Funktionen in PHP 8.2 bereinigt: ThemeUpdate / ThemeUpdateChecker
    mit #[AllowDynamicProperties] kommentiert; strpos/str_replace
    gegen Null-Werte abgesichert; DivisionByZero verhindert.
  • TGMPA (Bibliothek zur Plugin-Empfehlung) vollständig entfernt.

Leistung

  • Mitgelieferter Google-Fonts-Snapshot (inc/data/google-fonts.json, ~140 KB)
    — Die Schriftartauswahl im Customizer funktioniert offline, kein API-Schlüssel erforderlich.
  • fetchpriority="high" im Haupt-Stylesheet webseide-style
    (LCP-Hinweis).
  • Alle Theme-Skripte verzögert geladen über den Filter script_loader_tag.
  • webseide.js in die Fußzeile verschoben mit korrektem Cache-Schlüssel für die Theme-Version.
  • Google-Fonts-URLs: preconnect zu fonts.googleapis.com +
    fonts.gstatic.com, &display=swap bei allen Schriftart-Anfragen.
  • WP-Core-Emoji-Skript + Stile deaktiviert.
  • loadmore_posts-JS wird nur bei paginierten Archiven in die Warteschlange gestellt.
  • loadmore_comments-JS wird nur bei Einzelansichten mit paginierten
    Kommentaren in die Warteschlange gestellt; wp_count_comments() lokal zwischengespeichert (wurde 3× pro
    Anfrage aufgerufen).
  • Customizer-CSS: Transient-Cache mit festem Schlüssel, Invalidierung mit Platzhaltern
    beim Speichern von Anpassungen / Theme-Wechsel / Mod-Update; Objekt-Cache leeren;
    ?webseide_css_bust=1 für manuelle Umgehung; robuster Minifier.
  • Bereinigung von Leerzeichen in CSS/JS: Komprimierung von Banner-Kommentaren (–3 % bei
    style.css), abschließende Leerzeichen, Zusammenfassung von Leerzeilen – Struktur und
    Zeilenumbrüche bleiben erhalten.
  • Wiederholte get_theme_mod-Aufrufe werden in lokalen Variablen zwischengespeichert.
  • svg.js in die Warteschlange einreihen: korrektes Deps-Array + Version + Fußzeile.

Kopfzeile

  • Neue Auswahl „Kopfzeilenlayout“: Klassisch / siteweit in Box / pro
    Seite in Box (Umschaltung pro Seite in der Metabox „Design“).
  • Kopfzeilen-Eckenradius (px), Abstand oben (px, schwebende Kopfzeile)
    und Hintergrundunschärfe (px).
  • Ausrichtungsrichtung des mobilen Menüs: rechts / links / oben / unten / Einblenden —
    gesteuert durch die Body-Klasse, kein veraltetes right:-400px-Slide mehr.
  • Kontrollkästchen Automatische Höhe des mobilen Menüs — das Panel passt sich dem Inhalt an statt
    100vh, wird unter der Kopfzeile angedockt und übernimmt den Radius der Kopfzeile.
  • Option Ausrichtung des Desktop-Menüs: Zentriert hinzugefügt.
  • Farbe der Hamburger-Streifen mit Fallback auf die Schriftfarbe der Kopfzeile.

Blog / Inhalt

  • Meta-Informationen zu Beiträgen als Mehrfach-Checkbox neu gestaltet
    (Datum / Kategorie / Lesezeit). Autor dauerhaft entfernt.
  • Featured-Bild in Einzelbeiträgen deaktivieren als seitenweiser Schalter in der
    Metabox „Design“.
  • Mobile Blog-Widgets: scrollbar (mit Chevron-Hinweis) oder ausgeblendet
    hinter dem Filter-Button.
  • Optionen im Blog-Customizer neu sortiert (Mobile Blog-Widgets ganz oben).
  • Die veraltete Vorgabe „Maximale Breite/Höhe für Bild-Uploads“ wurde entfernt.
  • Autorenboxen und Autoreninfo-Blöcke wurden aus allen Vorlagen entfernt.
  • „Metainformationen in Beiträgen anzeigen“ wurde so korrigiert, dass es nun auch für
    Einzelbeiträge gilt.
  • H1 auf WooCommerce-Checkout-Seiten: Der globale Schalter „H1 auf Seiten ausblenden“
    wird nun bei is_checkout() ignoriert; der seitenbezogene Schalter im Block-Editor gilt weiterhin
    .
  • Schalter für Vorschaubilder wurden in die Metabox „Design“ verschoben (Archiv + Detailansicht
    Ansicht-Kontrollkästchen).
  • Metabox „Design“: Tabellenlayout durch gestapelte Beschriftungen ersetzt; das Feld für benutzerdefiniertes
    CSS verwendet den nativen WordPress-CodeMirror; Reihenfolge der Felder überarbeitet.

WooCommerce

  • Warenkorb-Seite: H1-Ausgabe erfolgt automatisch (berücksichtigt den seitenbezogenen Schalter).
  • Schalter „H1 bei Produktkategorien und Tags deaktivieren“.
  • Mini-Warenkorb-Bereich: „Progressleiste für kostenlosen Versand anzeigen“ – wird im
    blockbasierten Mini-Warenkorb-Drawer und auf der Warenkorbseite innerhalb von
    .woocommerce-shipping-totals gerendert; wird bei Änderungen im Warenkorb automatisch aktualisiert.
  • Anzeigemodus für mobile WooCommerce-Widgets (scrollbar / Filter-
    Schaltfläche) mit Filter-/Sortieren-Integration.
  • Einstellungen für Widget-Spalten umbenannt (oberhalb / unterhalb des Shop-Loops).
  • webseide_woocommerce_hide_product_sorting behoben (Einstellung existierte
    schon seit jeher, war aber nie implementiert).
  • .wc-block-mini-cart wird auf der Warenkorb-/Kassenseite nicht mehr ausgeblendet.
  • Mehrstufiger Checkout-Assistent: Der aktive Schritt verwendet Schaltflächenfarben.
  • .wc-block-mini-cart__button::before: Die Symbolfarbe wird über
    mask-image + currentColor übernommen.

Menüs

  • Bildauswahl für Menüeinträge pro Eintrag (im Customizer aktivieren, Größe
    • Position festlegen: oben / links / rechts).
  • Flags „Ist Überschrift im Dropdown-Menü“ und „Ist Spaltentrenner im Dropdown-
    Menü“
    pro Menüpunkt; reiner Spaltentrenner zeigt keinen sichtbaren Inhalt an, sondern
    löst lediglich einen CSS-Spaltenumbruch aus.
  • „Hat mehrere Spalten (Legacy)“ auf Menüpunkte der obersten Ebene beschränkt.
  • Überarbeitete vertikale Zentrierung von Menüpunkten der obersten Ebene (flex statt
    display: table-cell) – behebt den Überlauf bei der Schaltflächenhöhe.

Farben / Farbverläufe

  • Basis-Farbverlaufspalette (Abschnitt „Farben“) – 4 Plätze mit benutzerdefiniertem
    Farbwähler (Einfarbig / Linear / Radial + Hex-Farbeingaben + Winkel-Schieberegler).
    Ausgegeben als CSS-Variablen --wsg1..4.
  • Die Farbverläufe der Palette sind auch im Block-Editor als
    Farbverlaufsvoreinstellungen und als Farbpaletteneinträge mit CSS-Klassen-
    Hijack registriert – Farbverläufe können in jedem Block-Farbwähler (Text,
    Hintergrund, Rahmen) ausgewählt werden und werden, wo
    möglich, über background-clip: text gerendert.
  • Schaltflächen, Überschriften, Links: Farbverläufe können über denselben Farbwähler überschrieben werden.
  • Fokus-Stile: globale, nur über die Tastatur aktivierbare :focus-visible-Umrandung mit
    konfigurierbarer Akzentfarbe (Abschnitt „Schaltflächen und Formulare“).

i18n

  • Strings der „Versandkostenfrei“-Leiste für de_DE (du) und
    de_DE_formal (Sie) übersetzt.
  • Neu übersetzte Strings: Richtung des mobilen Menüs, Farbverläufe,
    Layoutoptionen für die Kopfzeile, umrahmte Kopfzeile, Unschärfe, Filter-Schaltfläche, Sortieren und Filtern,
    Farbe des Hamburger-Symbols.

Struktur

  • Anzeigename in LX1 umbenannt (Slug + Textdomain bleiben delucks-seo,
    um die Kompatibilität mit Updates des SEO-Plugins zu gewährleisten – das Theme ist davon nicht betroffen).
  • Plugin-i18n: Dual-Load-Muster, um zu beheben, dass leere w.org-Sprachpakete
    die gebündelten Übersetzungen überschreiben.
  • Zahlreiche Korrekturen von Tippfehlern, Entfernung von totem Code, Bereinigung der Kommentare.
  • Diverse Code-Aktualisierungen vorgenommen
  • Ausrichtungsfehler bei aktiviertem Blocksatz korrigiert
  • WooCommerce: Kategorie-Beschreibungs-Bug gelöst
  • Footer: Move to top nun auch mit Aria Label zur Barrierefreiheit
  • WooCommerce: Benutzerregistrierung und Anmeldung in zwei Spalten auf Desktop-Auflösung
  • WooCommerce: Visuelle Fehlerbehebungen für Kontrollkästchen
  • WooCommerce: Link zum Entfernen des Frontend-Profils für die DSGVO hinzugefügt
  • Optimierungen der Barrierefreiheit für das Hamburger-Menü und das Warenkorb-Symbol
  • Veralteten Code aufgeräumt