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

+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)", () => {