diff --git a/.claude/agents/3d-visual-lead.md b/.claude/agents/3d-visual-lead.md
index 2442b35..c7cb778 100644
--- a/.claude/agents/3d-visual-lead.md
+++ b/.claude/agents/3d-visual-lead.md
@@ -26,7 +26,7 @@ You are a senior 3D technical artist who has shipped production product configur
- **3D Stack**: React Three Fiber (`@react-three/fiber`), Drei (`@react-three/drei`), Three.js
- **Styling**: Tailwind CSS v4
- **Design Language**: Industrial, clean, heavy — Dark Grey/Black primary, Orange & Blue accents
-- **Texture Assets**: Located in `public/textures/aluwdoors/`
+- **Texture Assets**: Located in `public/textures/proinn/`
## Hard Constraints — DO NOT VIOLATE
@@ -46,7 +46,7 @@ You are a senior 3D technical artist who has shipped production product configur
- Build door geometry from composed primitives (frame, panels, glass inserts, handles) — not a single box.
4. **Texture-First Approach**:
- - ALWAYS check `public/textures/aluwdoors/` for available texture assets BEFORE falling back to procedural or flat colors.
+ - ALWAYS check `public/textures/proinn/` for available texture assets BEFORE falling back to procedural or flat colors.
- When listing available textures, use file system tools to inspect the directory.
- Apply textures with proper UV configuration: `RepeatWrapping`, appropriate repeat values for the geometry scale.
@@ -60,7 +60,7 @@ When tasked with visual improvements, follow this workflow:
- Identify gaps: flat colors where textures should be, missing shadows, poor lighting, sharp edges.
### Step 2: Inventory Available Assets
-- Scan `public/textures/aluwdoors/` and any other texture directories.
+- Scan `public/textures/proinn/` and any other texture directories.
- Catalog available maps: diffuse, normal, roughness, metalness, AO.
- Note texture resolutions and naming conventions.
@@ -69,9 +69,9 @@ When tasked with visual improvements, follow this workflow:
- Use `useTexture` from Drei for loading, with proper configuration:
```tsx
const [diffuse, normal, roughness] = useTexture([
- '/textures/aluwdoors/diffuse.jpg',
- '/textures/aluwdoors/normal.jpg',
- '/textures/aluwdoors/roughness.jpg',
+ '/textures/proinn/diffuse.jpg',
+ '/textures/proinn/normal.jpg',
+ '/textures/proinn/roughness.jpg',
])
// Configure wrapping and repeat
;[diffuse, normal, roughness].forEach(t => {
@@ -113,7 +113,7 @@ When tasked with visual improvements, follow this workflow:
Before considering any visual task complete, verify:
- [ ] No sharp BoxGeometry edges visible — all using RoundedBox
-- [ ] Textures from `public/textures/aluwdoors/` are applied where available
+- [ ] Textures from `public/textures/proinn/` are applied where available
- [ ] Materials have physically plausible PBR values (metalness, roughness, etc.)
- [ ] Lighting creates depth with visible highlights, mid-tones, and shadows
- [ ] Contact shadows ground the object in space
diff --git a/.claude/agents/frontend-stylist.md b/.claude/agents/frontend-stylist.md
index f33ad3f..0d0a3d7 100644
--- a/.claude/agents/frontend-stylist.md
+++ b/.claude/agents/frontend-stylist.md
@@ -1,6 +1,6 @@
---
name: frontend-stylist
-description: "Use this agent when you need to implement or refine visual styling, design system tokens, Tailwind CSS configurations, UI polish, responsive layouts, or translate reference CSS into Tailwind utility classes for the Proinn Configurator project. This agent is specifically for the 'Anti-Gravity' design system: floating cards, soft shadows, premium typography, and mobile-first responsive design.\\n\\nExamples:\\n\\n\\nContext: The user wants to apply the competitor's color palette from the scraped CSS file to the Tailwind config.\\nuser: \"Apply the colors from the aluwdoors reference CSS to our Tailwind config\"\\nassistant: \"I'll use the frontend-stylist agent to read the reference CSS and translate those color values into our Tailwind configuration.\"\\n\\nSince this is a styling task involving translating reference CSS into Tailwind config, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user has just built a new configurator step component and it needs styling.\\nuser: \"I just created step-dimensions.tsx, can you style it to match our design system?\"\\nassistant: \"I'll launch the frontend-stylist agent to apply the Anti-Gravity design system styles to the new step component.\"\\n\\nSince a new UI component needs styling with floating cards, shadows, and responsive design, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user notices the configurator looks broken on mobile.\\nuser: \"The configurator buttons are overlapping on iPhone, fix the mobile layout\"\\nassistant: \"I'll use the frontend-stylist agent to fix the mobile-first responsive layout for the configurator buttons.\"\\n\\nSince this is a mobile responsive styling issue in the configurator UI, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user wants to add smooth transitions and hover effects to the step cards.\\nuser: \"Make the option cards feel more premium with hover animations\"\\nassistant: \"I'll launch the frontend-stylist agent to implement smooth transitions and premium hover effects on the option cards.\"\\n\\nSince this involves UI polish, transitions, and visual refinement, use the Task tool to launch the frontend-stylist agent.\\n\\n"
+description: "Use this agent when you need to implement or refine visual styling, design system tokens, Tailwind CSS configurations, UI polish, responsive layouts, or translate reference CSS into Tailwind utility classes for the Proinn Configurator project. This agent is specifically for the 'Anti-Gravity' design system: floating cards, soft shadows, premium typography, and mobile-first responsive design.\\n\\nExamples:\\n\\n\\nContext: The user wants to apply the competitor's color palette from the scraped CSS file to the Tailwind config.\\nuser: \"Apply the colors from the proinn reference CSS to our Tailwind config\"\\nassistant: \"I'll use the frontend-stylist agent to read the reference CSS and translate those color values into our Tailwind configuration.\"\\n\\nSince this is a styling task involving translating reference CSS into Tailwind config, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user has just built a new configurator step component and it needs styling.\\nuser: \"I just created step-dimensions.tsx, can you style it to match our design system?\"\\nassistant: \"I'll launch the frontend-stylist agent to apply the Anti-Gravity design system styles to the new step component.\"\\n\\nSince a new UI component needs styling with floating cards, shadows, and responsive design, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user notices the configurator looks broken on mobile.\\nuser: \"The configurator buttons are overlapping on iPhone, fix the mobile layout\"\\nassistant: \"I'll use the frontend-stylist agent to fix the mobile-first responsive layout for the configurator buttons.\"\\n\\nSince this is a mobile responsive styling issue in the configurator UI, use the Task tool to launch the frontend-stylist agent.\\n\\n\\n\\n\\nContext: The user wants to add smooth transitions and hover effects to the step cards.\\nuser: \"Make the option cards feel more premium with hover animations\"\\nassistant: \"I'll launch the frontend-stylist agent to implement smooth transitions and premium hover effects on the option cards.\"\\n\\nSince this involves UI polish, transitions, and visual refinement, use the Task tool to launch the frontend-stylist agent.\\n\\n"
model: sonnet
color: cyan
memory: project
@@ -15,7 +15,7 @@ You are a world-class frontend stylist who thinks in Tailwind utility classes. Y
1. **Tailwind CSS**: Utility classes, arbitrary values (e.g., `h-[calc(100vh-80px)]`), `@apply` directives, responsive prefixes (`sm:`, `md:`, `lg:`, `xl:`), dark mode, animation utilities, and custom theme configuration.
2. **UI/UX Craft**: You ensure every interactive element feels tactile and intentional — buttons have satisfying hover states, transitions are buttery smooth (200-300ms ease-out), and spacing creates visual breathing room.
3. **Mobile-First Design**: You ALWAYS write mobile styles first, then layer on tablet and desktop enhancements. Every component must be fully functional and beautiful on a 375px viewport before you consider larger screens.
-4. **CSS Translation**: You excel at reading raw CSS files (especially `public/aluwdoors-ref/configurator.css`) and translating exact values — colors, border-radii, shadows, fonts, spacing — into precise Tailwind config entries or utility classes.
+4. **CSS Translation**: You excel at reading raw CSS files (especially `public/proinn-ref/configurator.css`) and translating exact values — colors, border-radii, shadows, fonts, spacing — into precise Tailwind config entries or utility classes.
## Tech Stack Context
@@ -71,7 +71,7 @@ Your design system principles:
## Workflow
-1. **Read First**: Before making changes, read the target file AND `public/aluwdoors-ref/configurator.css` (if relevant) to understand current state and reference values.
+1. **Read First**: Before making changes, read the target file AND `public/proinn-ref/configurator.css` (if relevant) to understand current state and reference values.
2. **Plan**: Briefly describe what styles you'll apply and why.
3. **Implement Mobile-First**: Write the mobile layout first. Test mentally at 375px.
4. **Layer Up**: Add `sm:`, `md:`, `lg:` responsive variants.
@@ -84,7 +84,7 @@ Your design system principles:
## Reference CSS Translation Protocol
-When translating from `public/aluwdoors-ref/configurator.css`:
+When translating from `public/proinn-ref/configurator.css`:
1. Read the CSS file carefully, extracting:
- Color values → Add to `tailwind.config.ts` under `theme.extend.colors`
@@ -102,7 +102,7 @@ When translating from `public/aluwdoors-ref/configurator.css`:
## Current Mission
-Your immediate task is to translate the scraped competitor styles from `public/aluwdoors-ref/configurator.css` — specifically colors, border-radius values, and shadow definitions — into our Tailwind config (`tailwind.config.ts`) and then apply them systematically to the configurator interface components. Ensure the result feels premium, industrial, and distinctly "Proinn" while borrowing the best UX patterns from the reference.
+Your immediate task is to translate the scraped competitor styles from `public/proinn-ref/configurator.css` — specifically colors, border-radius values, and shadow definitions — into our Tailwind config (`tailwind.config.ts`) and then apply them systematically to the configurator interface components. Ensure the result feels premium, industrial, and distinctly "Proinn" while borrowing the best UX patterns from the reference.
**Update your agent memory** as you discover design tokens, component styling patterns, responsive breakpoint decisions, and any CSS quirks or workarounds specific to this project. This builds up institutional knowledge across conversations. Write concise notes about what you found and where.
diff --git a/actions/send-quote.ts b/actions/send-quote.ts
new file mode 100644
index 0000000..b07bc91
--- /dev/null
+++ b/actions/send-quote.ts
@@ -0,0 +1,234 @@
+"use server";
+
+import { Resend } from "resend";
+
+const resend = new Resend(process.env.RESEND_API_KEY);
+
+interface QuoteRequest {
+ // Product
+ doorType: string;
+ gridType: string;
+ doorConfig: string;
+ sidePanel: string;
+
+ // Dimensions
+ width: number;
+ height: number;
+ doorLeafWidth: number;
+
+ // Options
+ finish: string;
+ glassColor: string;
+ handle: string;
+ frameSize: number;
+ glassPattern: string;
+
+ // Extras
+ extraOptions: string[];
+
+ // Contact
+ name: string;
+ email: string;
+ phone: string;
+ note: string;
+
+ // Pricing
+ totalPrice: number;
+ steelCost: number;
+ glassCost: number;
+ baseFee: number;
+ mechanismSurcharge: number;
+ sidePanelSurcharge: number;
+ handleCost: number;
+ finishSurcharge: number;
+
+ // Screenshot
+ screenshotDataUrl: string | null;
+}
+
+const LABEL_MAP: Record = {
+ taats: "Taatsdeur",
+ scharnier: "Scharnierdeur",
+ paneel: "Vast Paneel",
+ enkele: "Enkele deur",
+ dubbele: "Dubbele deur",
+ geen: "Geen",
+ links: "Links",
+ rechts: "Rechts",
+ beide: "Beide zijden",
+ zwart: "Mat Zwart",
+ brons: "Brons",
+ grijs: "Antraciet",
+ goud: "Goud",
+ beige: "Beige",
+ ral: "RAL Kleur",
+ helder: "Helder glas",
+ "mat-blank": "Mat Blank",
+ "mat-brons": "Mat Brons",
+ "mat-zwart": "Mat Zwart",
+ beugelgreep: "Beugelgreep",
+ hoekgreep: "Hoekgreep",
+ maangreep: "Maangreep",
+ ovaalgreep: "Ovaalgreep",
+ klink: "Deurklink",
+ "u-greep": "U-Greep",
+ standard: "Standaard",
+ "dt9-rounded": "DT9 Afgerond",
+ "dt10-ushape": "DT10 U-vorm",
+};
+
+function label(key: string): string {
+ return LABEL_MAP[key] || key;
+}
+
+function formatPrice(cents: number): string {
+ return new Intl.NumberFormat("nl-NL", {
+ style: "currency",
+ currency: "EUR",
+ minimumFractionDigits: 0,
+ maximumFractionDigits: 0,
+ }).format(cents);
+}
+
+function buildHtmlEmail(data: QuoteRequest): string {
+ const rows = [
+ ["Deurtype", label(data.doorType)],
+ ["Verdeling", data.gridType],
+ ["Configuratie", label(data.doorConfig)],
+ ["Zijpanelen", label(data.sidePanel)],
+ ["", ""],
+ ["Breedte (wandopening)", `${data.width} mm`],
+ ["Hoogte", `${data.height} mm`],
+ ["Deurblad breedte", `${Math.round(data.doorLeafWidth)} mm`],
+ ["", ""],
+ ["Afwerking", label(data.finish)],
+ ["Glaskleur", label(data.glassColor)],
+ ["Greep", label(data.handle)],
+ ["Profielbreedte", `${data.frameSize} mm`],
+ ["Glaspatroon", label(data.glassPattern)],
+ ];
+
+ if (data.extraOptions.length > 0) {
+ rows.push(["", ""], ["Extra opties", data.extraOptions.join(", ")]);
+ }
+
+ const tableRows = rows
+ .filter(([k]) => k !== "")
+ .map(
+ ([k, v]) =>
+ `
Wij hebben uw configuratie ontvangen en nemen zo snel mogelijk contact met u op.
+
+ Indicatieprijs: ${formatPrice(data.totalPrice)}
+ Dit is een indicatieprijs. De definitieve prijs wordt bepaald na opmeting.
+
+
+ Proinn Stalen Deuren | proinn.nl
+
+
+ `,
+ });
+
+ return { success: true };
+ } catch (error) {
+ console.error("Failed to send quote email:", error);
+ return {
+ success: false,
+ error: "Er is iets misgegaan bij het versturen. Probeer het opnieuw.",
+ };
+ }
+}
diff --git a/app/contact/page.tsx b/app/contact/page.tsx
new file mode 100644
index 0000000..2d86086
--- /dev/null
+++ b/app/contact/page.tsx
@@ -0,0 +1,218 @@
+import type { Metadata } from "next";
+import Link from "next/link";
+import { Mail, Phone, MapPin, Clock, ArrowRight } from "lucide-react";
+
+export const metadata: Metadata = {
+ title: "Contact | PROINN Stalen Deuren",
+ description:
+ "Neem contact op met Proinn voor vragen over stalen deuren, offertes of advies. Bel 0165 311 490 of mail info@proinn.nl.",
+};
+
+const contactMethods = [
+ {
+ icon: Phone,
+ title: "Bel ons",
+ value: "0165 311 490",
+ href: "tel:0165311490",
+ description: "Ma t/m vr: 08:00 - 17:00",
+ },
+ {
+ icon: Mail,
+ title: "E-mail",
+ value: "info@proinn.nl",
+ href: "mailto:info@proinn.nl",
+ description: "Reactie binnen 24 uur",
+ },
+ {
+ icon: MapPin,
+ title: "Bezoekadres",
+ value: "Schotsbossenstraat 2",
+ href: "https://maps.google.com/?q=Schotsbossenstraat+2+4705AG+Roosendaal",
+ description: "4705AG Roosendaal",
+ },
+ {
+ icon: Clock,
+ title: "Openingstijden",
+ value: "Ma t/m vr: 08:00 - 17:00",
+ href: undefined,
+ description: "Weekend op afspraak",
+ },
+];
+
+const faqItems = [
+ {
+ question: "Hoe lang duurt de levertijd?",
+ answer:
+ "De gemiddelde levertijd bedraagt 4 tot 6 weken na goedkeuring van de offerte. Dit kan vari\u00ebren afhankelijk van de complexiteit van het project en de drukte in onze werkplaats.",
+ },
+ {
+ question: "Verzorgen jullie ook de montage?",
+ answer:
+ "Ja, wij bieden een complete service van ontwerp tot montage. Onze eigen monteurs installeren uw deur vakkundig op locatie. U kunt er ook voor kiezen de deur zelf te (laten) plaatsen.",
+ },
+ {
+ question: "Kan ik een showroom bezoeken?",
+ answer:
+ "U bent van harte welkom in onze werkplaats in Roosendaal om onze producten in het echt te bekijken. Neem vooraf contact op zodat wij u de aandacht kunnen geven die u verdient.",
+ },
+ {
+ question: "Wat kost een stalen deur?",
+ answer:
+ "De prijs is afhankelijk van de afmetingen, het type deur, de glassoort en de gewenste afwerking. Gebruik onze online configurator voor een directe indicatieprijs, of vraag een offerte op maat aan.",
+ },
+ {
+ question: "Welke kleuren zijn beschikbaar?",
+ answer:
+ "Onze standaard kleuren zijn Zwart (RAL 9005), Antraciet, Brons, Goud en Beige. Daarnaast kunt u kiezen uit het volledige RAL-kleurenpalet voor een kleur die precies aansluit bij uw interieur.",
+ },
+ {
+ question: "Leveren jullie door heel Nederland?",
+ answer:
+ "Ja, wij leveren en monteren door heel Nederland en Belgi\u00eb. Onze monteurs komen bij u op locatie voor een perfecte installatie.",
+ },
+];
+
+export default function ContactPage() {
+ return (
+ <>
+ {/* Hero */}
+
+
+
+
+
+
+ Contact
+
+
+
+ Neem contact op
+
+
+ Heeft u vragen over onze stalen deuren, wilt u advies of bent u
+ klaar om een offerte aan te vragen? Wij staan voor u klaar.
+
- {/* Navigation — hidden on step 1 (auto-advances) and summary (has its own button) */}
+ {/* Navigation -- hidden on step 1 (auto-advances) and summary (has its own button) */}
{!isFirstStep && !isLastStep && (