diff --git a/README.md b/README.md index 00d08b0..15289d3 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ Selbst betreibbares Block-CMS für PHP-Webhosting mit visuellem Editor nach dem Die übernommenen Originaldokumente sind `AGENTS.md` und `ENTWICKLUNGSPLAN.md`. Den tatsächlichen Stand enthält `docs/STATUS.md`, Entscheidungen und Datenmodell stehen in `docs/ARCHITECTURE.md`. +## Bildecken unter Design (ab 1.21.0) + +Wie stark die Ecken der Bilder gerundet sind, steht jetzt unter **Design → Bildecken** und gilt für die ganze Website – Bilder, Galerien, Logoleisten und Beitragslisten. Vorgabe ist `12px` wie bisher, `0px` macht sie eckig. Ein einzelnes Bild lässt sich davon abweichend einstellen: im Editor beim ausgewählten Bild unter **Design → Bild → Bildecken**, dort auch je Gerät und je Ecke. Vorher stand die Rundung fest im Stylesheet und war in keinem Feld zu finden. + ## Kaufmännisches Und und Zeilenumbrüche bleiben, wie sie sind (ab 1.20.1) **Behoben.** Ein Text ohne Auszeichnung wurde beim Speichern doppelt kodiert: aus `&` wurde `&`, beim nächsten Speichern `&` – irgendwann stand die Entity sichtbar auf der Seite. Ebenso wuchsen Zeilenumbrüche: jedes zweite Speichern machte aus einem `
` zwei. Beides ist behoben, und wiederholtes Speichern ändert einen Text jetzt nicht mehr. Was bereits falsch gespeichert ist, räumt `php bin/console cms:repair:entities` auf: ohne Option zeigt er nur, was sich ändern würde, mit `--schreiben` wendet er es an. Angefasst werden die veröffentlichte Fassung und der Entwurf jeder Seite sowie die Bereiche; ältere Fassungen bleiben Historie. diff --git a/docs/STATUS.md b/docs/STATUS.md index 50b076e..1dfcf23 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -1,5 +1,17 @@ # Projektstatus +## Fassung 1.21.0: Bildecken gehören dem Designbereich (16.09.2026) + +**Anlass:** Umut zum Hero-Bild von DEEG: „Das sollte abgerundet sein, aber wurde von irgendwo gemacht, und die Ecken sehen komisch aus. Es gibt auch im Editor gar nicht Bildecken abrunden, oder?“ + +**Was los war.** `.block-image{border-radius:12px}` stand fest in `enhancements.css` – jedes Bild jeder Installation war gerundet, ohne dass ein Feld das gesagt hätte. Auf DEEG (eine durchgehend eckige Vorlage) fiel es auf, weil über dem gerundeten Bild eckige Elemente liegen: der dunkle Verlauf, das Schild, die blaue Aufruf-Fläche. An den Ecken schaute deshalb die eckige Fläche aus der Rundung heraus. + +**Behoben.** Die Ecken sind jetzt eine Einstellung unter **Design → Bildecken** (`theme.base.imageRadius`, geprüft wie die Inhaltsbreite, ausgegeben als `--k-image-radius`). Vorgabe bleibt `12px`, damit bestehende Websites gleich aussehen; `0px` macht alle Bilder eckig. Für ein einzelnes Bild gab es die Einstellung schon immer – im Editor unter **Design → Bild → Bildecken** (`imageRadius` im Stilschema, für Bild, Galerie, Logoleiste und Beitragsliste); sie überschreibt den Wert der Website. + +**DEEG:** `imageRadius` auf `0px`, im Aufbauskript und in der Installation. Das Hero-Bild ist damit eckig wie die Vorlage, und die Ecken stimmen wieder. + +**Geprüft:** neuer Test in `tests/CmsTest.php`: Vorgabe ist `12px`, eine Seite mit Bild trägt `--k-image-radius:12px`, nach dem Speichern von `0px` trägt sie `--k-image-radius:0px`, und „rund“ wird abgewiesen wie jede andere Nicht-Größenangabe. + ## Fassung 1.20.1: das kaufmännische Und, das bei jedem Speichern wuchs (16.09.2026) **Anlass:** Umut: „Beim Startseitenbild wird der Text & umgewandelt, aber in der Ansicht nach dem Speichern wird & daraus.“ diff --git a/public/assets/enhancements.css b/public/assets/enhancements.css index 267ab77..36a07ef 100644 --- a/public/assets/enhancements.css +++ b/public/assets/enhancements.css @@ -1,4 +1,4 @@ -.block-gallery{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-block:24px}.block-gallery>.block-image{min-width:0;margin:0}.block-gallery img{width:100%;aspect-ratio:4/3;object-fit:cover}.block-image figcaption{font-size:14px;line-height:1.5;padding:12px 0;color:inherit}.fx-shadow-none{box-shadow:none}.fx-shadow-soft{box-shadow:0 8px 24px #142e251f}.fx-shadow-strong{box-shadow:0 16px 40px #142e2540}.block-image{border-radius:12px}.block-image img{border-radius:inherit}.block-gallery:empty{min-height:32px}.fx-hover-zoom{overflow:hidden}.fx-hover-zoom img{transform-origin:center}.tone-ink figure{color:var(--paper)} +.block-gallery{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;margin-block:24px}.block-gallery>.block-image{min-width:0;margin:0}.block-gallery img{width:100%;aspect-ratio:4/3;object-fit:cover}.block-image figcaption{font-size:14px;line-height:1.5;padding:12px 0;color:inherit}.fx-shadow-none{box-shadow:none}.fx-shadow-soft{box-shadow:0 8px 24px #142e251f}.fx-shadow-strong{box-shadow:0 16px 40px #142e2540}.block-image{border-radius:var(--k-image-radius,12px)}.block-image img{border-radius:inherit}.block-gallery:empty{min-height:32px}.fx-hover-zoom{overflow:hidden}.fx-hover-zoom img{transform-origin:center}.tone-ink figure{color:var(--paper)} @media(max-width:1024px){.block-gallery{grid-template-columns:repeat(2,minmax(0,1fr))}} @media(max-width:767px){.block-gallery{grid-template-columns:minmax(0,1fr);gap:16px}} .fx-hover-lift,.fx-hover-zoom img{transition:transform .25s ease}.fx-hover-lift:hover,.fx-hover-lift:focus-within{transform:translateY(-4px)}.fx-hover-zoom:hover img,.fx-hover-zoom:focus-within img{transform:scale(1.035)} diff --git a/scripts/seed-immobilien-deeg.php b/scripts/seed-immobilien-deeg.php index aa3be80..b0bbd9f 100644 --- a/scripts/seed-immobilien-deeg.php +++ b/scripts/seed-immobilien-deeg.php @@ -283,7 +283,7 @@ $theme->save( ['key' => 'body', 'name' => 'Fließtext', 'family' => 'Arial', 'source' => 'system', 'weights' => [400, 600, 700], 'fallback' => 'sans-serif'], ['key' => 'heading', 'name' => 'Überschriften', 'family' => 'Arial', 'source' => 'system', 'weights' => [400, 700], 'fallback' => 'sans-serif'], ], - ['fontFamily' => 'body', 'headingFontFamily' => 'heading', 'fontSize' => '16px', 'lineHeight' => 1.6, 'color' => '@anthrazit', 'backgroundColor' => '@papier', 'linkColor' => '@anthrazit', 'containerWidth' => '1320px', 'headingScale' => 1.25, 'linkUnderline' => false], + ['fontFamily' => 'body', 'headingFontFamily' => 'heading', 'fontSize' => '16px', 'lineHeight' => 1.6, 'color' => '@anthrazit', 'backgroundColor' => '@papier', 'linkColor' => '@anthrazit', 'containerWidth' => '1320px', 'headingScale' => 1.25, 'linkUnderline' => false, 'imageRadius' => '0px'], ['shape' => 'square', 'appearance' => 'solid', 'size' => 'normal', 'fontFamily' => 'inherit', 'fontSize' => 14, 'fontWeight' => 600, 'letterSpacing' => 0, 'textTransform' => 'none', 'backgroundColor' => '@blau-tief', 'color' => '@papier', 'hoverBackgroundColor' => '@blau-dunkel', 'hoverColor' => '@papier'], ); echo "Farben, Schriften und Buttons gesetzt\n"; diff --git a/src/Content/Theme.php b/src/Content/Theme.php index 862796e..82b3120 100644 --- a/src/Content/Theme.php +++ b/src/Content/Theme.php @@ -68,6 +68,10 @@ final class Theme 'linkColor' => '@link', 'containerWidth' => '1240px', 'headingScale' => 1.25, + // Die Ecken jedes Bildes auf der Website. Stand bis 1.20.2 fest im Stylesheet - + // sichtbar gerundet, aber in keinem Feld zu finden. 12px bleibt die Vorgabe, + // damit bestehende Websites gleich aussehen; 0px macht Bilder eckig. + 'imageRadius' => '12px', // Unterstrichene Links im Fließtext. An, weil ein Link, den nur die Farbe verrät, // für Menschen mit Farbsehschwäche kein Link ist. Wer eine ruhigere Seite will, // schaltet es hier ab - dann bleibt der Unterstrich beim Überfahren. @@ -229,7 +233,7 @@ final class Theme } $base[$field] = $value; } - foreach (['fontSize', 'containerWidth'] as $field) { + foreach (['fontSize', 'containerWidth', 'imageRadius'] as $field) { $value = trim((string) ($input[$field] ?? $base[$field])); if (1 !== preg_match(StyleSchema::LENGTH, $value)) { throw new InvalidPage(sprintf('„%s“ ist keine Größenangabe wie 18px oder 70rem.', $value)); @@ -338,6 +342,7 @@ final class Theme } $base = $theme['base']; $variables[] = sprintf('--k-container:%s', $base['containerWidth']); + $variables[] = sprintf('--k-image-radius:%s', $base['imageRadius']); $colour = static fn (string $v): string => str_starts_with($v, '@') ? sprintf('var(--k-%s)', substr($v, 1)) : $v; diff --git a/templates/admin/theme.html.twig b/templates/admin/theme.html.twig index 1135620..374c495 100644 --- a/templates/admin/theme.html.twig +++ b/templates/admin/theme.html.twig @@ -162,6 +162,11 @@

1,25 ergibt eine ruhige Staffelung, 1,5 eine sehr kontrastreiche.

+
+ + +

Gilt für jedes Bild auf der Website – auch in Galerien, Logoleisten und Beitragslisten. 0px macht sie eckig. Ein einzelnes Bild lässt sich im Editor unter Design → Bild → Bildecken abweichend einstellen.

+
diff --git a/tests/CmsTest.php b/tests/CmsTest.php index 31b08d7..9f4d1ba 100644 --- a/tests/CmsTest.php +++ b/tests/CmsTest.php @@ -3111,6 +3111,34 @@ final class CmsTest extends TestCase $code->assertScriptsUnchanged($added, $before); } + public function testImageCornersComeFromTheDesignAreaAndCanBeSquare(): void + { + // Die Ecken jedes Bildes standen fest im Stylesheet: sichtbar gerundet, in keinem Feld + // zu finden, nur durch einen eigenen Wert am Block loszuwerden. Jetzt gehoeren sie dem + // Designbereich - mit derselben Vorgabe wie vorher, damit sich nichts veraendert. + $theme = $this->themes->load(); + self::assertSame('12px', $theme['base']['imageRadius'], 'Die Vorgabe bleibt, was vorher im Stylesheet stand.'); + + $document = DemoContent::starter('Mit Bild'); + $document['blocks'][0]['children'][] = ['id' => 'bild', 'type' => 'image', 'props' => ['src' => '/assets/image-placeholder.svg', 'alt' => 'Platzhalter', 'decorative' => false, 'width' => 1000, 'height' => 600]]; + $id = $this->publishedPage('ecken', 'Ecken'); + $stand = $this->pages->findForEditor($id); + $this->pages->publish($id, $this->pages->saveDraft($id, $document, $stand['version']), $this->pages->findForEditor($id)['version']); + + self::assertStringContainsString('--k-image-radius:12px', $this->request('/ecken')->getContent()); + + // Eckig, wie es eine Vorlage ohne Rundungen braucht. + $this->themes->save($theme['colors'], $theme['fonts'], [...$theme['base'], 'imageRadius' => '0px']); + self::assertStringContainsString('--k-image-radius:0px', $this->request('/ecken')->getContent()); + + // Und was keine Groessenangabe ist, wird abgewiesen - wie bei der Inhaltsbreite. + try { + $this->themes->save($theme['colors'], $theme['fonts'], [...$theme['base'], 'imageRadius' => 'rund']); + self::fail('„rund“ ist keine Groessenangabe.'); + } catch (InvalidPage) { + } + } + public function testSavingTextTwiceKeepsAmpersandsAndLineBreaksAsTheyAre(): void { // Umut: „Beim Startseitenbild wird & umgewandelt, aber nach dem Speichern steht &