feat: redesign page heroes, implement organic markers, and streamline contact flow
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 1m24s
Build & Deploy / 🏗️ Build (push) Failing after 4m3s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 5s

- Refined hero sections for About, Blog, Websites, and Case Studies for a bespoke industrial entry point.
- Redesigned Marker component using layered SVG paths for an organic, hand-drawn highlighter effect.
- Restored technical precision in ArchitectureVisualizer with refined line thickness.
- Streamlined contact page by removing generic headers and prioritizing the configurator/gateway.
- Updated technical references to reflect self-hosted Gitea infrastructure.
- Cleaned up unused imports and addressed linting warnings across modified pages.
This commit is contained in:
2026-02-16 19:34:08 +01:00
parent cb32b9d62f
commit 9cfe7ee9e5
58 changed files with 3231 additions and 1592 deletions

20
apps/web/src/lib/env.ts Normal file
View File

@@ -0,0 +1,20 @@
import { z } from "zod";
import { validateMintelEnv } from "@mintel/next-utils";
/**
* Environment variable schema extension.
*/
const envExtension = {
// Mail Configuration
MAIL_HOST: z.string().optional(),
MAIL_PORT: z.coerce.number().optional().default(587),
MAIL_USER: z.string().optional(),
MAIL_PASS: z.string().optional(),
MAIL_FROM: z.string().optional().default("marc@mintel.me"),
MAIL_RECIPIENTS: z.string().optional().default("marc@mintel.me"),
};
/**
* Validated environment object.
*/
export const env = validateMintelEnv(envExtension);

View File

@@ -0,0 +1,85 @@
import nodemailer from "nodemailer";
import { env } from "../env";
let transporterInstance: nodemailer.Transporter | null = null;
function getTransporter() {
if (transporterInstance) return transporterInstance;
if (!env.MAIL_HOST) {
// In development, we might not have mail configured, so we log instead of throwing
if (process.env.NODE_ENV === "development") {
console.warn(
"MAIL_HOST is not configured. Emails will be logged to console.",
);
return null;
}
throw new Error(
"MAIL_HOST is not configured. Please check your environment variables.",
);
}
transporterInstance = nodemailer.createTransport({
host: env.MAIL_HOST,
port: env.MAIL_PORT,
secure: env.MAIL_PORT === 465,
auth: {
user: env.MAIL_USER,
pass: env.MAIL_PASS,
},
});
return transporterInstance;
}
interface SendEmailOptions {
to?: string | string[];
replyTo?: string;
subject: string;
html: string;
}
export async function sendEmail({
to,
replyTo,
subject,
html,
}: SendEmailOptions) {
const recipients = to || env.MAIL_RECIPIENTS;
const transporter = getTransporter();
const mailOptions = {
from: env.MAIL_FROM,
to: recipients,
replyTo,
subject,
html,
};
if (!transporter) {
console.log("--- EMAIL SIMULATION ---");
console.log("To:", recipients);
console.log("Subject:", subject);
console.log("HTML Output suppressed");
console.log("--- END SIMULATION ---");
return { success: true, messageId: "simulated-id" };
}
try {
const info = await transporter.sendMail(mailOptions);
console.log("Email sent successfully", {
messageId: info.messageId,
subject,
recipients,
});
return { success: true, messageId: info.messageId };
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
console.error("Error sending email", {
error: errorMsg,
subject,
recipients,
});
return { success: false, error: errorMsg };
}
}