Abschluss-CTA: durchgehender Verlauf statt weicher Kreise

Die beiden blur-Kreise ueber dem Hellblau wirkten als Flecken – der dunkle
rechts unten am staerksten. Ersetzt durch .cta-band in shared-styles.css: ein
durchgehender Verlauf ueber die volle Breite, von Anthrazit diagonal in das
Dynamic Blue, beides aus den Theme-Variablen.

- Tiefe kommt aus dem Verlauf, nicht aus ueberlagerten Flaechen.
- Zwei Haarlinien als Kontur: eine oben ueber die Breite, eine als Auftakt
  ueber der Ueberschrift, beide zu den Seiten auslaufend.
- Buttons filigraner: duennerer Rahmen beim Outline-Button, weicherer Schatten
  beim Hauptbutton.

Der Verlauf liegt als CSS-Klasse vor und nicht als Utility-Kette im Blade,
damit er mit den Theme-Variablen arbeitet und ueber alle Themes stimmt.

Tests: 862 gruen (3192 Assertions), Pint sauber, npm run build:b2in gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-03 10:12:20 +00:00
parent f971f416db
commit 3ee7b44a77
5 changed files with 81 additions and 20 deletions

View file

@ -52,6 +52,7 @@ public/img/logos/b2in-interior-logo-negative.png
public/img/logos/b2in-interior-logo-negative.svg public/img/logos/b2in-interior-logo-negative.svg
public/img/logos/b2in-interior-logo-positive.png public/img/logos/b2in-interior-logo-positive.png
public/img/logos/b2in-interior-logo-positive.svg public/img/logos/b2in-interior-logo-positive.svg
resources/css/web/shared-styles.css
resources/lang/de/b2in.php resources/lang/de/b2in.php
resources/lang/de/ui.php resources/lang/de/ui.php
resources/lang/en/b2in.php resources/lang/en/b2in.php

View file

@ -19,7 +19,7 @@ eingearbeitet. Offen: Bildmaterial, Rechtstexte und die Herstellerfreigaben.
**Stand 03.09.2026:** T1 und B1–B13 abgearbeitet, **alle Arbeitspakete AP0–AP6 umgesetzt**, die **Stand 03.09.2026:** T1 und B1–B13 abgearbeitet, **alle Arbeitspakete AP0–AP6 umgesetzt**, die
Bestandsinhalte auf den Interior-Auftritt umgestellt, die Seite abgestimmt und alle vier Punkte Bestandsinhalte auf den Interior-Auftritt umgestellt, die Seite abgestimmt und alle vier Punkte
der Abstimmungsrunde vom 03.09. umgesetzt (Nachtrag 5). Alle drei Markenseiten haben jetzt einen der Abstimmungsrunde vom 03.09. umgesetzt (Nachtrag 5). Alle drei Markenseiten haben jetzt einen
ausführlichen Text. `php artisan test --compact`: **861 grün** (3189 Assertions), Pint sauber, ausführlichen Text. `php artisan test --compact`: **862 grün** (3192 Assertions), Pint sauber,
`npm run build:b2in` gebaut. `npm run build:b2in` gebaut.
**Die Seite ist testbereit** – die ausstehenden Zulieferungen trägt Marcel selbst im CMS nach. **Die Seite ist testbereit** – die ausstehenden Zulieferungen trägt Marcel selbst im CMS nach.
@ -977,12 +977,22 @@ transportiert. Der Badge am Bild („Visualisierung") trägt die Unterscheidung
Der Block war eine einfarbige Fläche mit Überschrift, Text, Button und einem unterstrichenen Der Block war eine einfarbige Fläche mit Überschrift, Text, Button und einem unterstrichenen
Textlink. Neu: Textlink. Neu:
- Zwei weiche Lichtflächen (`blur-3xl`) nehmen dem Volltonhintergrund die Härte.
- Eine schmale Linie über der Überschrift setzt den Abschluss ab. - Eine schmale Linie über der Überschrift setzt den Abschluss ab.
- Hauptbutton weiß auf Markenfarbe, mit Pfeil, der beim Hovern mitgeht. - Hauptbutton weiß auf Markenfarbe, mit Pfeil, der beim Hovern mitgeht.
- Die Herstellerseite ist jetzt ein gleichwertiger Outline-Button statt eines Textlinks. - Die Herstellerseite ist jetzt ein gleichwertiger Outline-Button statt eines Textlinks.
- Der Showroom steht als kleine Zeile mit Pin-Symbol darunter. - Der Showroom steht als kleine Zeile mit Pin-Symbol darunter.
**Nachgebessert (zweite Rückmeldung):** Der erste Versuch legte zwei weiche Kreise (`blur-3xl`)
über das Hellblau – die wirkten als sichtbare Flecken, besonders der dunkle rechts unten. Ersetzt
durch einen durchgehenden Verlauf über die volle Breite: `.cta-band` in `shared-styles.css`, von
Anthrazit (`--primary-dark`) diagonal in das Dynamic Blue (`--secondary-dark`). Die Tiefe kommt
aus dem Verlauf selbst, die Kontur aus zwei Haarlinien – eine oben über die Breite, eine als
Auftakt über der Überschrift, beide zu den Seiten auslaufend. Buttons und Fußzeile dabei
zurückhaltender: dünnerer Rahmen, weicherer Schatten.
> Der Verlauf liegt bewusst als CSS-Klasse vor und nicht als Utility-Kette im Blade: er arbeitet
> mit den Theme-Variablen und bleibt so über alle Themes hinweg stimmig.
Die Textinhalte kommen unverändert aus dem CMS (`cta_title` / `cta_text`) – Punkt 4 der Liste war Die Textinhalte kommen unverändert aus dem CMS (`cta_title` / `cta_text`) – Punkt 4 der Liste war
inhaltlich bereits durch die neuen Texte erledigt („Ihre Küche. Persönlich geplant."). inhaltlich bereits durch die neuen Texte erledigt („Ihre Küche. Persönlich geplant.").
@ -1025,8 +1035,9 @@ dasselbe Verhalten.
- Jede Vertiefung rendert zugeklappt und mit der Höhen-Animation; die alte Sprung-Bewegung ist - Jede Vertiefung rendert zugeklappt und mit der Höhen-Animation; die alte Sprung-Bewegung ist
weg. weg.
- Weder Markenseite noch FAQ verwenden noch den Flächen-Hover. - Weder Markenseite noch FAQ verwenden noch den Flächen-Hover.
- Der Abschlussblock trägt das Verlaufsband; die weichen Kreise sind weg.
`php artisan test --compact`: **861 grün** (3189 Assertions), Pint sauber, `npm run build:b2in` `php artisan test --compact`: **862 grün** (3192 Assertions), Pint sauber, `npm run build:b2in`
gebaut. gebaut.
--- ---

View file

@ -258,6 +258,51 @@ h1, h2, h3, h4, h5, h6 {
color: hsl(var(--dark-text)); color: hsl(var(--dark-text));
} }
/* Abschlussband der Markenseiten.
Ein durchgehender Verlauf ueber die volle Breite: von Anthrazit in das
Dynamic Blue. Bewusst ohne weiche Kreise – die setzten sichtbare Flecken in
die Ecken. Die Tiefe kommt aus dem Verlauf selbst, die Kontur aus zwei
Haarlinien. */
.cta-band {
position: relative;
overflow: hidden;
background: linear-gradient(
100deg,
hsl(var(--primary-dark)) 0%,
hsl(var(--primary)) 42%,
hsl(var(--secondary-dark)) 100%
);
}
/* Lichtkante oben, die zu beiden Seiten auslaeuft. */
.cta-band::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(
90deg,
transparent 0%,
hsl(0 0% 100% / 0.35) 50%,
transparent 100%
);
}
/* Sehr flacher Schimmer von oben links, damit die Flaeche nicht flach wirkt. */
.cta-band::after {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background: linear-gradient(
165deg,
hsl(0 0% 100% / 0.07) 0%,
transparent 48%
);
}
.text-dark-muted { .text-dark-muted {
color: hsl(var(--dark-muted)); color: hsl(var(--dark-muted));
} }

View file

@ -100,9 +100,9 @@
{{-- Weiches Auf- und Zuklappen ueber grid-template-rows (0fr → 1fr): {{-- Weiches Auf- und Zuklappen ueber grid-template-rows (0fr → 1fr):
das animiert die tatsaechliche Hoehe, waehrend x-show den Inhalt das animiert die tatsaechliche Hoehe, waehrend x-show den Inhalt
schlagartig einblendet. Das Alpine-Collapse-Plugin ist in diesem schlagartig einblendet. Das Alpine-Collapse-Plugin ist in diesem
Projekt nicht registriert, dies kommt ohne Abhaengigkeit aus. --}} Projekt nicht registriert, dies kommt ohne Abhaengigkeit aus.
{{-- Der zugeklappte Zustand steht auch im statischen class-Attribut, Der zugeklappte Zustand steht auch im statischen class-Attribut,
damit vor dem Start von Alpine nichts aufgeklappt aufblitzt. Die damit vor dem Start von Alpine nichts aufgeklappt aufblitzt – die
Objekt-Schreibweise von x-bind:class entfernt ihn beim Oeffnen. --}} Objekt-Schreibweise von x-bind:class entfernt ihn beim Oeffnen. --}}
<div id="detail-{{ $index }}" <div id="detail-{{ $index }}"
class="grid grid-rows-[0fr] opacity-0 transition-all duration-500 ease-[cubic-bezier(0.33,1,0.68,1)]" class="grid grid-rows-[0fr] opacity-0 transition-all duration-500 ease-[cubic-bezier(0.33,1,0.68,1)]"
@ -282,18 +282,14 @@
</section> </section>
@endif @endif
{{-- 5. Abschluss. Der Block schliesst die Seite ab und traegt den Claim aus der Zulieferung – {{-- 5. Abschluss. Der Block schliesst die Seite ab und traegt den Claim aus der Zulieferung.
deshalb weiche Lichtflaechen statt Volltonhintergrund und ein gesetzter Hauptbutton Der durchgehende Verlauf steckt in `.cta-band` (shared-styles.css) – als Utility-Klassen
statt eines Textlinks. --}} waere er nicht ueber alle Themes hinweg zu halten. --}}
<section class="section-padding bg-secondary text-secondary-foreground relative overflow-hidden"> <section class="section-padding cta-band text-secondary-foreground">
{{-- Rein dekorativ: zwei weiche Lichtpunkte nehmen der Flaeche die Haerte. --}}
<div aria-hidden="true" class="pointer-events-none absolute inset-0">
<div class="absolute -top-40 left-1/2 h-96 w-[42rem] -translate-x-1/2 rounded-full bg-white/10 blur-3xl"></div>
<div class="absolute -bottom-48 -right-24 h-96 w-96 rounded-full bg-black/20 blur-3xl"></div>
</div>
<div class="container-narrow relative text-center"> <div class="container-narrow relative text-center">
<span aria-hidden="true" class="mx-auto block h-px w-16 bg-white/40"></span> {{-- Haarlinie als Auftakt, laeuft zu beiden Seiten aus. --}}
<span aria-hidden="true"
class="mx-auto block h-px w-24 bg-gradient-to-r from-transparent via-white/50 to-transparent"></span>
<h2 class="text-section-title text-white mt-8 text-balance"> <h2 class="text-section-title text-white mt-8 text-balance">
{{ $brand['cta_title'] ?: __('ui.brand_cta_title', ['name' => $brand['name']]) }} {{ $brand['cta_title'] ?: __('ui.brand_cta_title', ['name' => $brand['name']]) }}
@ -304,7 +300,7 @@
<div class="mt-10 flex flex-col sm:flex-row flex-wrap items-center justify-center gap-4"> <div class="mt-10 flex flex-col sm:flex-row flex-wrap items-center justify-center gap-4">
<a href="{{ route('contact') }}" <a href="{{ route('contact') }}"
class="group inline-flex items-center justify-center gap-2 rounded-lg bg-white px-8 py-4 text-lg font-medium text-secondary shadow-lg transition-all duration-300 hover:-translate-y-0.5 hover:shadow-xl"> class="group inline-flex items-center justify-center gap-2 rounded-lg bg-white px-8 py-4 text-lg font-medium text-secondary shadow-[0_12px_30px_-14px_rgba(0,0,0,0.65)] transition-all duration-300 hover:-translate-y-0.5 hover:shadow-[0_18px_38px_-14px_rgba(0,0,0,0.7)]">
{{ __('ui.request_appointment') }} {{ __('ui.request_appointment') }}
<svg class="h-5 w-5 transition-transform duration-300 group-hover:translate-x-1" fill="none" <svg class="h-5 w-5 transition-transform duration-300 group-hover:translate-x-1" fill="none"
stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"> stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true">
@ -314,7 +310,7 @@
@if (!empty($brand['website_url'])) @if (!empty($brand['website_url']))
<a href="{{ $brand['website_url'] }}" target="_blank" rel="noopener" <a href="{{ $brand['website_url'] }}" target="_blank" rel="noopener"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-white/40 px-8 py-4 text-lg text-white transition-colors duration-300 hover:bg-white/10"> class="inline-flex items-center justify-center gap-2 rounded-lg border border-white/25 px-8 py-4 text-lg text-white/90 transition-colors duration-300 hover:border-white/50 hover:text-white">
{{ __('ui.brand_website') }} {{ __('ui.brand_website') }}
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"
aria-hidden="true"> aria-hidden="true">
@ -326,7 +322,7 @@
</div> </div>
@if (!empty($brand['showroom'])) @if (!empty($brand['showroom']))
<p class="mt-10 inline-flex items-center gap-2 text-sm text-white/70"> <p class="mt-10 inline-flex items-center gap-2 text-sm text-white/65">
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" <svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"
aria-hidden="true"> aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" /> <path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" />

View file

@ -133,6 +133,14 @@ it('falls back to the generic closing block for a brand without one', function (
->assertSee('Interesse an CABINET?'); ->assertSee('Interesse an CABINET?');
}); });
it('closes the page with a gradient band across the full width', function () {
$html = $this->get('/marken/rotpunkt')->assertSuccessful()->getContent();
expect($html)->toContain('cta-band')
// Die weichen Kreise setzten sichtbare Flecken in die Ecken statt eines Verlaufs.
->and($html)->not->toContain('blur-3xl');
});
// ======================================== // ========================================
// Beschriftung des Terminanfrage-Widgets // Beschriftung des Terminanfrage-Widgets
// ======================================== // ========================================