Portal-Screenshots im Geräteformat neu aufgenommen

iPhone 16 Pro 402 x 874 (Safe Area 59/34) und MacBook-Safari-Fläche 1512 x 893,
je @2x, weiter nur mit den Demodaten der Bäckerei Sonnenschein. Kein Versatz
mehr im iPhone; im letzten Schritt bleibt die Statusleiste deckend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-01 18:54:23 +00:00
1 parent e0e81b65a8
commit c9ad9ba2b7
52 files changed
+32 -22

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

+5 -5
View File
@@ -31,22 +31,22 @@ SCHRITT = 4
KB = 1024
BUDGET_DESKTOP = 120 * KB
BUDGET_HANDY = 60 * KB
# Der lange Screenshot ist gut dreimal so hoch wie ein Handy-Bild (5428 statt 1688 px). Sein Budget
# Der lange Screenshot ist gut dreimal so hoch wie ein Handy-Bild (5131 statt 1748 px). Sein Budget
# wächst mit der Höhe (je Bildschirmhöhe weiterhin unter 60 KB), sonst wäre der Text nur noch Matsch.
BUDGET_LANG = {390: 80 * KB, 780: 150 * KB}
# Unter der letzten Inhaltszeile (Zeile 5179) ist der Rohexport nur noch schwarz. Abgeschnitten wird
# Unter der letzten Inhaltszeile (Zeile 5091) ist der Rohexport nur noch schwarz. Abgeschnitten wird
# 40 px darunter, sonst endet die Verschiebung im Handy-Rahmen auf einem leeren Streifen.
LANG_HOEHE = 5219
LANG_HOEHE = 5131
# Dateiname (ohne .webp) -> (Art, Zielbreiten)
BILDER = {
# Desktop-Fenster (Roh 2880 x 1800)
# Desktop-Fenster (Roh 3024 x 1786 = MacBook-Safari-Fläche 1512 x 893 @2x)
"desktop-1-projekte": ("desktop", (800, 1200, 1600)),
"desktop-2-fortschritt": ("desktop", (800, 1200, 1600)),
"desktop-3b-chat-foto": ("desktop", (800, 1200, 1600)),
"desktop-4-rechnungen": ("desktop", (800, 1200, 1600)),
"desktop-7-news-pinnwand": ("desktop", (800, 1200, 1600)),
# Handy (Roh 780 x 1688, das lange Bild 780 x 5428, beschnitten auf 5219)
# Handy (Roh 804 x 1748 = iPhone 16 Pro @2x, Safe Area 59/34; das lange Bild 804 x 5340, beschnitten auf 5131)
"phone-1-projekte": ("handy", (390, 780)),
"phone-3-projektdetails": ("handy", (390, 780)),
"phone-4b-chat-foto": ("handy", (390, 780)),
+2 -2
View File
@@ -59,8 +59,8 @@ export const DesktopFenster = ({ bild, children, className, adresse = "project.w
);
/**
* Handy: iPhone 16 Pro (Inhalt in 402 x 874). Die Portal-Aufnahmen haben oben nur 47 px (Roh, 2x)
* Rand für die Statusleiste; damit Dynamic Island nichts verdeckt, beginnt das Bild 35 px tiefer.
* Handy: iPhone 16 Pro (Inhalt in 402 x 874). Die Portal-Aufnahmen sind genau in diesem Format
* mit Safe Area 59 / 34 aufgenommen, Statusleiste und Home-Balken liegen also passend darüber.
*/
export const HandyRahmen = ({ bild, children, className }: RahmenProps) => (
<IPhoneFrame className={className}>
-3
View File
@@ -12,6 +12,3 @@
object-fit: cover;
object-position: top;
}
.wk-geraet-inhalt--handy {
top: 35px;
}
+7 -6
View File
@@ -22,18 +22,19 @@ const HANDY_BREITEN = [390, 780];
const srcSet = (name: string, breiten: number[]) =>
breiten.map((b) => `${BILDER}/${name}-${b}.webp ${b}w`).join(", ");
/** Desktop-Bild: Rohformat 2880 x 1800, ausgeliefert in 800 / 1200 / 1600 px. */
/** Desktop-Bild: Rohformat 3024 x 1786 (MacBook-Safari-Fläche 1512 x 893 @2x), ausgeliefert in 800 / 1200 / 1600 px. */
const desktopBild = (name: string, alt: string): RahmenBildDaten => ({
src: `${BILDER}/${name}-1200.webp`,
srcSet: srcSet(name, DESKTOP_BREITEN),
sizes: "(min-width: 1200px) 692px, 50vw",
width: 1600,
height: 1000,
height: 945,
alt,
});
/** Handy-Bild: Rohformat 780 x 1688 (das lange Bild 780 x 5219), ausgeliefert in 390 / 780 px. */
const handyBild = (name: string, alt: string, sizes: string, hoehe = 1688): RahmenBildDaten => ({
/** Handy-Bild: Rohformat 804 x 1748 = iPhone 16 Pro @2x (das lange Bild 804 x 5131), ausgeliefert in 390 / 780 px;
* width/height geben das Seitenverhältnis bei 780 px an. */
const handyBild = (name: string, alt: string, sizes: string, hoehe = 1696): RahmenBildDaten => ({
src: `${BILDER}/${name}-780.webp`,
srcSet: srcSet(name, HANDY_BREITEN),
sizes,
@@ -291,7 +292,7 @@ const Buehne = () => {
>
{f.lang ? (
<div className="kp-lang">
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 340px, 30vw", 5219)} />
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 340px, 30vw", 4978)} />
</div>
) : (
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 230px, 20vw")} />
@@ -326,7 +327,7 @@ const LangeKarte = ({ f }: { f: Funktion }) => {
<div className="kp-karte" ref={ref} data-sichtbar={sichtbar ? "ja" : "nein"}>
<HandyRahmen className="kp-karte__handy">
<div className="kp-lang">
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "250px", 5219)} />
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "250px", 4978)} />
</div>
</HandyRahmen>
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
+16 -4
View File
@@ -213,8 +213,8 @@
transform: translate(-35.9cqw, -14.2cqw) scale(1.5);
}
/* Der lange Screenshot: gleiche Breite wie der Schirm, 68,81 % seiner Höhe wandern aus dem Bild
(sichtbar sind 839 von 2690 px im iPhone-Inhalt). Die Verschiebung hängt am Scrollfortschritt (--kp-q), kein eigener Scrollbereich. */
/* Der lange Screenshot: gleiche Breite wie der Schirm, 65,93 % seiner Höhe wandern aus dem Bild
(sichtbar sind 874 von 2565,5 px im iPhone-Inhalt, 1 - 1748 / 5131). Die Verschiebung hängt am Scrollfortschritt (--kp-q), kein eigener Scrollbereich. */
.kp-lang {
position: absolute;
top: 0;
@@ -237,7 +237,7 @@
transition: transform var(--dur-enter) var(--ease);
}
.kp-buehne .kp-lang {
transform: translateY(calc(var(--kp-q, 0) * -68.81%));
transform: translateY(calc(var(--kp-q, 0) * -65.93%));
}
/* die große Ebene nur im letzten Schritt auf die Grafikkarte legen */
.kp-buehne[data-app="ja"] .kp-lang {
@@ -280,7 +280,7 @@
transform: translateY(0);
}
100% {
transform: translateY(-68.81%);
transform: translateY(-65.93%);
}
}
@@ -334,3 +334,15 @@
.kp-schritt-karte .kp-schritt__nr {
margin-bottom: 0;
}
/* Wie in der echten Portal-App ist die Statusleiste deckend: der lange Screenshot läuft darunter
durch, statt mit Uhrzeit und Symbolen zu überlappen (59 px = Safe Area oben im iPhone-Inhalt). */
.wk-geraet-inhalt:has(.kp-lage.is-aktiv .kp-lang)::after,
.wk-geraet-inhalt:has(> .kp-lang)::after {
content: "";
position: absolute;
inset: 0 0 auto 0;
height: 59px;
background: radial-gradient(70% 160% at 50% 0%, #1e0b31 0%, #000 100%);
z-index: 1;
}
+2 -2
View File
@@ -127,10 +127,10 @@ describe("Kundenportal: Bilder (Spezifikation 9.5)", () => {
expect(bilder).toHaveLength(6);
for (const bild of bilder.slice(0, 5)) {
expect(bild.getAttribute("width")).toBe("780");
expect(bild.getAttribute("height")).toBe("1688");
expect(bild.getAttribute("height")).toBe("1696");
}
expect(bilder[5].getAttribute("src")).toContain("phone-2-projekte-lang");
expect(bilder[5].getAttribute("height")).toBe("5219");
expect(bilder[5].getAttribute("height")).toBe("4978");
});
it("Desktop: zu Beginn hängen nur die ersten beiden Schritte ihre Bilder ein (spart Daten)", () => {