fix(mail): Willkommensmail-Kopf ohne Bildzwang – Logo als HTML, Welle als Streifen
Rueckmeldung des Nutzers: in Outlook nur ein grosser schwarzer Kasten, kein Logo (das eingebettete Kopfbild wurde nicht angezeigt; Logo und Schriftzug steckten nur darin). Jetzt Bildmarke aus Tabellenzellen und Schriftzug als Text in einer niedrigen dunklen Leiste, darunter die Duenen-Welle als 600x56-Streifen, der ins Weiss auslaeuft; fehlt das Bild, bleibt nur Abstand. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,10 +11,10 @@
|
||||
* Mail sehr unterschiedlich darstellen:
|
||||
* - Tabellenlayout, alle Stile inline, hoechstens 600 px breit;
|
||||
* - keine externen Ressourcen, keine Web-Fonts (Systemschriften);
|
||||
* - der Kopf im Stil des Dashboard-Hintergrunds "Duenen" ist ein PNG
|
||||
* (`headerImageSrc`, im Versand `cid:`), weil SVG und CSS-Hintergruende in
|
||||
* Outlook nicht erscheinen; fehlt das Bild, steht dort ein dunkler
|
||||
* Textkopf;
|
||||
* - Kopf: Bildmarke und Schriftzug als HTML (erscheinen immer), darunter
|
||||
* die Duenen-Welle als schmaler PNG-Streifen (`headerImageSrc`, im
|
||||
* Versand `cid:`), weil SVG und CSS-Hintergruende in Outlook nicht
|
||||
* erscheinen; fehlt das Bild, bleibt nur ein schmaler Abschluss;
|
||||
* - Knoepfe als Tabelle mit Hintergrundfarbe in der Zelle ("bulletproof"),
|
||||
* Outlook ignoriert Innenabstaende und Rundungen am Link selbst.
|
||||
*
|
||||
@@ -118,13 +118,58 @@ function button(href: string, label: string, bg: string, fg: string): string {
|
||||
</td></tr></table>`;
|
||||
}
|
||||
|
||||
/** Eine Kachel der Bildmarke: feste Zelle, Hoehe auch in Outlook exakt. */
|
||||
function tile(color: string | null): string {
|
||||
const bg = color ? `bgcolor="${color}" style="background-color:${color};` : 'style="';
|
||||
return `<td width="9" height="9" ${bg}width:9px;height:9px;font-size:1px;line-height:9px;mso-line-height-rule:exactly;"> </td>`;
|
||||
}
|
||||
|
||||
/** Luecke zwischen Kacheln. */
|
||||
const GAP = '<td width="3" style="width:3px;font-size:1px;line-height:1px;"> </td>';
|
||||
|
||||
/**
|
||||
* Bildmarke als HTML (quick-260930): das Kachel-"T" aus Tabellenzellen —
|
||||
* oben drei Kacheln (die dritte gelb, im Original gedreht), darunter zwei in
|
||||
* der Mitte —, auf dunkler Grundplatte mit heller Kontur wie in der App.
|
||||
* Braucht kein Bild und erscheint deshalb in jedem Mailprogramm.
|
||||
*/
|
||||
function logoMark(): string {
|
||||
const row = (cells: Array<string | null>) =>
|
||||
`<tr>${cells.map((c, i) => (i > 0 ? GAP : '') + tile(c)).join('')}</tr>`;
|
||||
const spacer = `<tr><td colspan="5" height="3" style="height:3px;font-size:1px;line-height:3px;mso-line-height-rule:exactly;"> </td></tr>`;
|
||||
const olive = '#9c9440';
|
||||
return `<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse:separate;">
|
||||
<tr><td bgcolor="#111214" style="background-color:#111214;border:1px solid #3a3d44;border-radius:10px;padding:10px 10px 10px 10px;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
|
||||
${row([olive, olive, C.yellow])}${spacer}${row([null, olive, null])}${spacer}${row([null, olive, null])}
|
||||
</table>
|
||||
</td></tr></table>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kopf der Mail (quick-260930, Rueckmeldung des Nutzers: in Outlook "ein
|
||||
* riesiger schwarzer Fleck, kein Logo"). Vorher steckten Logo und
|
||||
* Schriftzug in EINEM 150 px hohen Bild; zeigt ein Mailprogramm das
|
||||
* eingebettete Bild nicht an, blieb nur die dunkle Flaeche. Jetzt:
|
||||
* - Bildmarke (HTML-Kacheln) und Schriftzug "Tessera" (echter Text) in einer
|
||||
* niedrigen dunklen Leiste — erscheinen immer;
|
||||
* - darunter die Duenen-Welle als schmaler Bildstreifen (`src`, im Versand
|
||||
* `cid:`), der ins Weiss der Karte auslaeuft. Fehlt er, bleibt nur weisser
|
||||
* Abstand, kein dunkler Block.
|
||||
*/
|
||||
function headerRow(src: string | null): string {
|
||||
if (src) {
|
||||
return `<tr><td bgcolor="${C.header}" style="background-color:${C.header};border-radius:12px 12px 0 0;line-height:0;font-size:0;">
|
||||
<img src="${escapeHtml(src)}" width="600" height="150" alt="Tessera" style="display:block;width:100%;max-width:600px;height:auto;border:0;outline:none;text-decoration:none;border-radius:12px 12px 0 0;color:#ffffff;font-family:${FONT};font-size:28px;font-weight:700;">
|
||||
const bar = `<tr><td bgcolor="${C.header}" style="background-color:${C.header};border-radius:12px 12px 0 0;padding:22px 32px 14px;">
|
||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr>
|
||||
<td valign="middle" style="padding:0 14px 0 0;">${logoMark()}</td>
|
||||
<td valign="middle" style="font-family:${FONT};font-size:26px;line-height:32px;font-weight:700;color:#ffffff;letter-spacing:-0.5px;">Tessera</td>
|
||||
</tr></table>
|
||||
</td></tr>`;
|
||||
}
|
||||
return `<tr><td bgcolor="${C.header}" style="background-color:${C.header};border-radius:12px 12px 0 0;padding:40px 40px 36px;font-family:${FONT};font-size:30px;line-height:36px;font-weight:700;color:#ffffff;border-bottom:3px solid ${C.yellow};">Tessera</td></tr>`;
|
||||
const wave = src
|
||||
? `<tr><td bgcolor="${C.card}" style="background-color:${C.card};line-height:0;font-size:0;">
|
||||
<img src="${escapeHtml(src)}" width="600" height="56" alt="" style="display:block;width:100%;max-width:600px;height:auto;border:0;outline:none;text-decoration:none;">
|
||||
</td></tr>`
|
||||
: `<tr><td bgcolor="${C.header}" height="4" style="background-color:${C.header};height:4px;font-size:1px;line-height:4px;border-bottom:3px solid ${C.yellow};"> </td></tr>`;
|
||||
return bar + wave;
|
||||
}
|
||||
|
||||
export function renderWelcomeMail(input: WelcomeMailInput): RenderedWelcomeMail {
|
||||
|
||||
Reference in New Issue
Block a user