diff --git a/assets/img/app-symbole/analyse-180.png b/assets/img/app-symbole/analyse-180.png index db1bfabf..018ac048 100644 Binary files a/assets/img/app-symbole/analyse-180.png and b/assets/img/app-symbole/analyse-180.png differ diff --git a/assets/img/app-symbole/cloud-180.png b/assets/img/app-symbole/cloud-180.png index e22e4643..91388f51 100644 Binary files a/assets/img/app-symbole/cloud-180.png and b/assets/img/app-symbole/cloud-180.png differ diff --git a/assets/img/app-symbole/git-180.png b/assets/img/app-symbole/git-180.png index adbd8090..9d1c816b 100644 Binary files a/assets/img/app-symbole/git-180.png and b/assets/img/app-symbole/git-180.png differ diff --git a/assets/img/app-symbole/portal-180.png b/assets/img/app-symbole/portal-180.png index 2b17a7a6..dd1193c8 100644 Binary files a/assets/img/app-symbole/portal-180.png and b/assets/img/app-symbole/portal-180.png differ diff --git a/assets/img/app-symbole/universe-180.png b/assets/img/app-symbole/universe-180.png index d4abeb66..97fb492c 100644 Binary files a/assets/img/app-symbole/universe-180.png and b/assets/img/app-symbole/universe-180.png differ diff --git a/assets/img/app-symbole/verwaltung-180.png b/assets/img/app-symbole/verwaltung-180.png index ee086c8b..6db569bf 100644 Binary files a/assets/img/app-symbole/verwaltung-180.png and b/assets/img/app-symbole/verwaltung-180.png differ diff --git a/assets/img/app-symbole/wdverwalt-180.png b/assets/img/app-symbole/wdverwalt-180.png index 03a7eb23..d64787c1 100644 Binary files a/assets/img/app-symbole/wdverwalt-180.png and b/assets/img/app-symbole/wdverwalt-180.png differ diff --git a/assets/img/app-symbole/webdesign-180.png b/assets/img/app-symbole/webdesign-180.png index 47725094..9920373c 100644 Binary files a/assets/img/app-symbole/webdesign-180.png and b/assets/img/app-symbole/webdesign-180.png differ diff --git a/assets/img/app-symbole/workspace-180.png b/assets/img/app-symbole/workspace-180.png index 0151c311..33c3593f 100644 Binary files a/assets/img/app-symbole/workspace-180.png and b/assets/img/app-symbole/workspace-180.png differ diff --git a/assets/img/app-symbole/zocker-180.png b/assets/img/app-symbole/zocker-180.png index 98c931ee..21f53bf6 100644 Binary files a/assets/img/app-symbole/zocker-180.png and b/assets/img/app-symbole/zocker-180.png differ diff --git a/server/pruef-struktur.mjs b/server/pruef-struktur.mjs index 1d7b8c40..4d416f71 100644 --- a/server/pruef-struktur.mjs +++ b/server/pruef-struktur.mjs @@ -341,6 +341,66 @@ console.log(` : `alle ${hinterWand.length} stehen in der Ausnahmeliste`); } +/* ---------- 10. Sind die Symbole fuer JEDES Geraet richtig gebaut? ------- + + PC und Handy holen ihr Symbol an drei verschiedenen Stellen, und + jede stellt andere Anforderungen: + + Browser-Reiter das normale Symbol, darf runde Ecken haben + Android die maskable-Fassung, davon wird aussen bis zu + ein Fuenftel weggeschnitten + iPhone -- und iOS rundet + SELBST ab und fuellt alles Durchsichtige mit + SCHWARZ + + Der letzte Punkt ist der, der auffiel ("auf dem einen klappt es und + auf dem anderen nicht"): Ein apple-touch-icon mit eigener Rundung + bekommt auf dem iPhone schwarze Zipfel. Auf dem PC sieht dieselbe + Datei tadellos aus -- deshalb faellt es nur auf einem der beiden + Geraete auf, und deshalb muss es gemessen werden statt angesehen. + + Geprueft werden die Dateinamen, nicht die Bilder selbst -- die + Bildpruefung braucht einen Browser und laeuft in pruef-symbole.mjs. + Hier geht es darum, dass ueberhaupt fuer jede App und jedes Geraet + eine Datei da ist. */ +console.log(` +=== Symbole fuer alle Geraete ===`); +{ + const symOrdner = join(REPO, "assets", "img", "app-symbole"); + if (!existsSync(symOrdner)) { + ok(false, "der Ordner assets/img/app-symbole fehlt"); + } else { + const da = readdirSync(symOrdner); + const apps = [...new Set(da.map((n) => n.replace(/-(\d+)(-maskable)?\.png$/, "")))] + .filter((n) => n.endsWith(".png") === false); + ok(apps.length >= 8, `${apps.length} Apps mit eigenen Symbolen`); + + const noetig = ["192", "512", "192-maskable", "512-maskable", "180", "32"]; + const fehlend = []; + for (const a of apps) { + for (const g of noetig) { + if (!da.includes(`${a}-${g}.png`)) fehlend.push(`${a}-${g}.png`); + } + } + ok(fehlend.length === 0, + fehlend.length ? `fehlende Symbole: ${fehlend.slice(0, 6).join(", ")}` + : `alle ${apps.length * noetig.length} Symbole vorhanden ` + + `(Reiter, Android-maskable, iPhone)`); + + /* Jede Seite muss BEIDES nennen: das Reiter-Symbol und das fuers + iPhone. Fehlt das zweite, nimmt iOS einen Bildschirmausschnitt + der Seite -- unbrauchbar und unerkennbar. */ + let ohneApple = []; + for (const seite of seiten) { + const text = readFileSync(join(WS, seite), "utf8"); + if (!/rel="apple-touch-icon"/i.test(text)) ohneApple.push(seite); + } + ok(ohneApple.length === 0, + ohneApple.length ? `ohne apple-touch-icon (iPhone nimmt sonst einen Screenshot): ${ohneApple.join(", ")}` + : `alle ${seiten.length} Workspace-Seiten nennen ein iPhone-Symbol`); + } +} + /* ---------- Gegenprobe --------------------------------------------------- */ console.log(`\n=== Gegenprobe (muss anschlagen) ===`); diff --git a/tools/app-symbole.mjs b/tools/app-symbole.mjs index 950a6470..1d02ddd4 100644 --- a/tools/app-symbole.mjs +++ b/tools/app-symbole.mjs @@ -317,7 +317,7 @@ export const STIL_JE_APP = { * Jede Kachel bekommt deshalb einen eigenen Namen aus Stil und App. * Damit lässt sich beliebig viel davon in ein Dokument legen, ohne * dass sich zwei ins Gehege kommen. */ -export function symbolTeil(f, stilName, n, { maskable = false, logoDaten } = {}) { +export function symbolTeil(f, stilName, n, { maskable = false, apple = false, logoDaten } = {}) { const stil = STILE[stilName]; const logoFilter = typeof stil.logo === "function" ? stil.logo(f) : stil.logo; @@ -345,8 +345,23 @@ export function symbolTeil(f, stilName, n, { maskable = false, logoDaten } = {}) 78 % ist der Anteil, der bei jeder gaengigen Maske heil bleibt (Kreis, Quadrat mit runden Ecken, Tropfen). */ - const radius = maskable ? 0 : 22.4; // 22,4 % ist die Apple-Rundung - const k = `s-${stilName}-${f.schluessel}${maskable ? "-m" : ""}`; + /* APPLE-TOUCH-ICON: quadratisch, undurchsichtig, OHNE eigene Rundung. + + BEFUND 05.09.2026 ("auf dem einen klappt es und auf dem anderen + nicht"). iOS holt sein Symbol NICHT aus dem Manifest, sondern aus + . Und es behandelt diese Datei anders + als jeder andere Browser: Es rundet die Ecken SELBST ab und fuellt + alles Durchsichtige mit SCHWARZ. + + Unser Symbol brachte seine eigene Rundung mit -- also durchsichtige + Ecken. Auf dem iPhone wurden daraus schwarze Zipfel, die dann ein + zweites Mal beschnitten wurden. Auf dem PC faellt das nicht auf, + weil Windows und Chrome mit Transparenz umgehen koennen. Genau + daher der Unterschied zwischen den beiden Geraeten. + + Deshalb hier: randvoll, eckig, deckend. Die Rundung macht iOS. */ + const radius = (maskable || apple) ? 0 : 22.4; // 22,4 % ist die Apple-Rundung + const k = `s-${stilName}-${f.schluessel}${maskable ? "-m" : ""}${apple ? "-a" : ""}`; /* Das eigentliche Symbol ist bei maskable kleiner als die Datei. */ const innen = maskable ? Math.round(n * 0.78) : n; @@ -527,7 +542,7 @@ const GROESSEN = [ { n: 512, maskable: false, endung: "512" }, { n: 192, maskable: true, endung: "192-maskable" }, { n: 512, maskable: true, endung: "512-maskable" }, - { n: 180, maskable: false, endung: "180" }, + { n: 180, maskable: false, apple: true, endung: "180" }, { n: 32, maskable: false, endung: "32" }, ]; @@ -551,7 +566,7 @@ async function bauen() { } for (const g of GROESSEN) { await seite.setViewportSize({ width: g.n, height: g.n }); - await seite.setContent(symbolHtml(f, stilName, g.n, { maskable: g.maskable, logoDaten }), + await seite.setContent(symbolHtml(f, stilName, g.n, { maskable: g.maskable, apple: g.apple, logoDaten }), { waitUntil: "networkidle" }); await seite.waitForTimeout(60); const datei = join(ziel, `${f.schluessel}-${g.endung}.png`);