Replaces em dashes with en dashes across all hardcoded copy, emails, and seed content, then reworks the site's visual language so it reads as deliberately designed rather than assembled from generic components: - New ArrowLink component replaces ad hoc "Mehr erfahren ->" links and ghost buttons; one shared FormField (TextField/TextAreaField) replaces 7 near-duplicate field styles across every form - Navbar loses its glassmorphism blur for a solid warm background, gets a subtle active-link underline and a softer, warmer mega-menu - PageHeader supports per-page blob tone/position and a compact mode instead of an identical band on every interior page - Homepage: the core offer is featured large instead of four equal cards, the philosophy section gets a single calmer accent blob, blog teasers now show their cover image like the real /aktuelles page does - Booking calendar and widget: 44px touch targets throughout (month nav, day cells, time slots, cancel action), a visible "today" ring, and responsive padding so the calendar isn't cramped on small screens - Quieter, warmer empty states on /termine and /aktuelles No functional changes: all interaction logic (nav menus, forms, booking, CMS data fetching) is untouched, only markup and styling.
115 lines
4.9 KiB
TypeScript
115 lines
4.9 KiB
TypeScript
export type ReminderEmailData = {
|
||
recipientName: string;
|
||
eventTitle: string;
|
||
dateLabel: string;
|
||
timeLabel: string;
|
||
joinUrl: string;
|
||
meetingPassword: string;
|
||
minutesBefore: number;
|
||
};
|
||
|
||
const colors = {
|
||
mauveDark: "#8b616d",
|
||
plum: "#66505f",
|
||
cream: "#f2e2d6",
|
||
creamLight: "#fbf6f1",
|
||
};
|
||
|
||
/** Table-based HTML email (inline styles only) matching the ANOUMA design. */
|
||
export function renderReminderEmailHtml(data: ReminderEmailData): string {
|
||
const { recipientName, eventTitle, dateLabel, timeLabel, joinUrl, meetingPassword, minutesBefore } = data;
|
||
|
||
return `<!doctype html>
|
||
<html lang="de">
|
||
<body style="margin:0;padding:0;background:${colors.creamLight};font-family:Georgia,'Times New Roman',serif;">
|
||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background:${colors.creamLight};padding:32px 16px;">
|
||
<tr>
|
||
<td align="center">
|
||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:480px;background:#ffffff;border-radius:24px;overflow:hidden;">
|
||
<tr>
|
||
<td style="background:${colors.mauveDark};padding:28px 32px;text-align:center;">
|
||
<span style="color:#ffffff;font-size:22px;letter-spacing:0.12em;font-weight:600;">ANOUMA</span>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="padding:32px;">
|
||
<p style="margin:0 0 20px;color:${colors.plum};font-size:16px;line-height:1.6;">
|
||
Hallo ${escapeHtml(recipientName)},
|
||
</p>
|
||
<p style="margin:0 0 24px;color:${colors.plum};font-size:18px;line-height:1.6;font-style:italic;">
|
||
Dein Online-Termin bei ANOUMA beginnt in ${minutesBefore} Minuten.
|
||
</p>
|
||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background:${colors.cream};border-radius:16px;">
|
||
<tr>
|
||
<td style="padding:20px 24px;">
|
||
<p style="margin:0 0 12px;color:${colors.plum};font-size:14px;">
|
||
<strong>Termin:</strong><br />${escapeHtml(eventTitle)}
|
||
</p>
|
||
<p style="margin:0 0 12px;color:${colors.plum};font-size:14px;">
|
||
<strong>Datum:</strong><br />${escapeHtml(dateLabel)}
|
||
</p>
|
||
<p style="margin:0;color:${colors.plum};font-size:14px;">
|
||
<strong>Uhrzeit:</strong><br />${escapeHtml(timeLabel)} Uhr
|
||
</p>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:28px auto;">
|
||
<tr>
|
||
<td style="border-radius:999px;background:${colors.mauveDark};">
|
||
<a href="${joinUrl}" style="display:inline-block;padding:14px 32px;color:#ffffff;text-decoration:none;font-size:14px;font-weight:600;letter-spacing:0.02em;">
|
||
Meeting betreten
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<p style="margin:0 0 4px;color:${colors.plum};font-size:14px;">
|
||
<strong>Meeting-Passwort:</strong>
|
||
</p>
|
||
<p style="margin:0 0 20px;color:${colors.plum};font-size:20px;letter-spacing:0.08em;font-family:'Courier New',monospace;">
|
||
${escapeHtml(meetingPassword)}
|
||
</p>
|
||
<p style="margin:0;color:${colors.plum};font-size:13px;line-height:1.6;">
|
||
Bitte halte dein Passwort bereit. Beim Betreten des Meetings wirst du außerdem nach deinem Namen gefragt.
|
||
</p>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="padding:20px 32px;background:${colors.cream};text-align:center;">
|
||
<span style="color:${colors.plum};font-size:12px;">Räume für Verbindung – mit dir selbst, miteinander und mit der Natur.</span>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</body>
|
||
</html>`;
|
||
}
|
||
|
||
export function renderReminderEmailText(data: ReminderEmailData): string {
|
||
const { recipientName, eventTitle, dateLabel, timeLabel, joinUrl, meetingPassword, minutesBefore } = data;
|
||
return [
|
||
`Hallo ${recipientName},`,
|
||
"",
|
||
`Dein Online-Termin bei ANOUMA beginnt in ${minutesBefore} Minuten.`,
|
||
"",
|
||
`Termin: ${eventTitle}`,
|
||
`Datum: ${dateLabel}`,
|
||
`Uhrzeit: ${timeLabel} Uhr`,
|
||
"",
|
||
`Meeting betreten: ${joinUrl}`,
|
||
`Meeting-Passwort: ${meetingPassword}`,
|
||
"",
|
||
"Bitte halte dein Passwort bereit. Beim Betreten des Meetings wirst du außerdem nach deinem Namen gefragt.",
|
||
].join("\n");
|
||
}
|
||
|
||
function escapeHtml(value: string): string {
|
||
return value
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">")
|
||
.replace(/"/g, """);
|
||
}
|