diff --git a/lib/KLZLogoVector.tsx b/lib/KLZLogoVector.tsx
new file mode 100644
index 00000000..5555e3e8
--- /dev/null
+++ b/lib/KLZLogoVector.tsx
@@ -0,0 +1,153 @@
+import React from 'react';
+import { Svg, G, Path } from '@react-pdf/renderer';
+
+export const KLZLogoVector = ({ width, color }: { width: number; color: string }) => {
+ // Original viewBox was 0 0 295 99, so height is width * 99 / 295
+ const height = width * (99 / 295);
+ return (
+
+ );
+};
diff --git a/lib/pdf-business-card.tsx b/lib/pdf-business-card.tsx
index 67993760..ef8d29b5 100644
--- a/lib/pdf-business-card.tsx
+++ b/lib/pdf-business-card.tsx
@@ -1,5 +1,6 @@
import React from 'react';
-import { Document, Page, Text, View, StyleSheet, Font, Image } from '@react-pdf/renderer';
+import { Document, Page, Text, View, StyleSheet, Svg, Line, Image } from '@react-pdf/renderer';
+import { KLZLogoVector } from './KLZLogoVector';
export interface PersonData {
name: string;
@@ -10,112 +11,147 @@ export interface PersonData {
interface PDFBusinessCardProps {
person: PersonData;
- logoWhitePath: string;
- logoBluePath: string;
- logoFullPath: string;
- truckImagePath: string;
qrCodeDataUrl: string;
}
+// Mintel Aesthetics Colors
+const COLORS = {
+ navy: '#001a4d',
+ navyLight: '#002870',
+ green: '#82ed20',
+ white: '#ffffff',
+ grayText: '#8899aa',
+ darkText: '#000000',
+ lightGray: '#f0f0f0',
+};
+
const styles = StyleSheet.create({
- page: {
- width: '85mm',
- height: '55mm',
- backgroundColor: '#ffffff',
- position: 'relative',
- fontFamily: 'Helvetica',
- },
pageBleed: {
// 85x55mm + 3mm bleed on each side = 91x61mm
width: '91mm',
height: '61mm',
- backgroundColor: '#ffffff',
+ backgroundColor: COLORS.navy,
position: 'relative',
fontFamily: 'Helvetica',
overflow: 'hidden',
},
- // FRONT PAGE
+ pageBleedBack: {
+ width: '91mm',
+ height: '61mm',
+ backgroundColor: COLORS.white,
+ position: 'relative',
+ fontFamily: 'Helvetica',
+ overflow: 'hidden',
+ },
+
+ // -- FRONT --
frontContainer: {
flex: 1,
position: 'relative',
padding: '8mm',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
},
- frontLogo: {
+ frontLogoPos: {
position: 'absolute',
- top: '5mm',
- right: '5mm',
- width: '25mm',
+ top: '8mm',
+ right: '8mm',
},
- truckImage: {
+ frontGraphicContainer: {
position: 'absolute',
- bottom: '-2mm',
- left: '-5mm',
- width: '100mm', // cover bleed width
- height: '50mm',
- objectFit: 'contain',
+ bottom: '-3mm',
+ left: '-3mm',
+ right: '-3mm',
+ height: '30mm',
+ backgroundColor: COLORS.navyLight,
+ borderTopWidth: 2,
+ borderTopColor: COLORS.green,
},
- // BACK PAGE
+ frontTagline: {
+ position: 'absolute',
+ bottom: '8mm',
+ left: '8mm',
+ color: COLORS.green,
+ fontSize: 10,
+ fontWeight: 'bold',
+ letterSpacing: 1.5,
+ },
+ gridLine: {
+ position: 'absolute',
+ backgroundColor: 'rgba(255,255,255,0.05)',
+ },
+
+ // -- BACK --
backContainer: {
flex: 1,
position: 'relative',
padding: '6mm 6mm',
},
backLogo: {
- width: '20mm',
- marginBottom: '8mm',
+ marginBottom: '6mm',
},
backMiddle: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: '8mm',
+ width: '100%',
},
nameSection: {
flexDirection: 'column',
width: '35%',
},
nameText: {
- fontSize: 16,
- fontWeight: 700,
- color: '#000000',
+ fontSize: 14,
+ fontWeight: 'bold',
+ color: COLORS.navy,
marginBottom: 2,
},
roleText: {
- fontSize: 8,
- fontWeight: 400,
- color: '#333333',
+ fontSize: 7.5,
+ fontWeight: 'normal',
+ color: COLORS.grayText,
+ letterSpacing: 0.5,
},
contactSection: {
flexDirection: 'column',
width: '45%',
paddingLeft: '2mm',
+ borderLeftWidth: 1,
+ borderLeftColor: COLORS.lightGray,
},
contactRow: {
flexDirection: 'row',
alignItems: 'center',
- marginBottom: 3,
+ marginBottom: 4,
},
iconCircle: {
- width: 12,
- height: 12,
- borderRadius: 6,
- backgroundColor: '#82ed20',
- justifyContent: 'center',
- alignItems: 'center',
- marginRight: 4,
+ width: 10,
+ height: 10,
+ borderRadius: 5,
+ backgroundColor: COLORS.green,
+ marginRight: 5,
},
contactText: {
fontSize: 6.5,
- fontWeight: 500,
- color: '#000000',
+ color: COLORS.navy,
},
qrSection: {
width: '20%',
alignItems: 'flex-end',
},
+ qrCodeWrapper: {
+ width: '16mm',
+ height: '16mm',
+ padding: 2,
+ backgroundColor: COLORS.white,
+ borderWidth: 1,
+ borderColor: COLORS.lightGray,
+ },
qrCode: {
- width: '18mm',
- height: '18mm',
+ width: '100%',
+ height: '100%',
},
footer: {
position: 'absolute',
@@ -123,49 +159,99 @@ const styles = StyleSheet.create({
left: '6mm',
right: '6mm',
flexDirection: 'row',
- justifyContent: 'center',
+ justifyContent: 'flex-start',
alignItems: 'center',
+ borderTopWidth: 1,
+ borderTopColor: COLORS.lightGray,
+ paddingTop: '2mm',
},
footerText: {
- fontSize: 6.5,
- fontWeight: 500,
- color: '#000000',
+ fontSize: 6,
+ color: COLORS.grayText,
+ letterSpacing: 0.5,
},
pipe: {
- fontSize: 6.5,
- fontWeight: 500,
- color: '#82ed20',
- marginHorizontal: 3,
+ fontSize: 6,
+ color: COLORS.green,
+ marginHorizontal: 4,
+ fontWeight: 'bold',
+ },
+ greenBar: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: '3mm',
+ height: '61mm',
+ backgroundColor: COLORS.green,
},
});
-export const PDFBusinessCard: React.FC = ({
- person,
- logoFullPath,
- truckImagePath,
- qrCodeDataUrl,
-}) => {
+// A simple technical grid background for the industrial aesthetic
+const IndustrialGrid = () => (
+
+);
+
+export const PDFBusinessCard: React.FC = ({ person, qrCodeDataUrl }) => {
return (
- {/* FRONT - 91x61mm with Bleed */}
+ {/* FRONT - Dark Navy Industrial */}
-
-
+
+
+
+
+
+
+
+
+
+
+ INDUSTRIAL CABLE SOLUTIONS
- {/* BACK - 91x61mm with Bleed */}
-
+ {/* BACK - Clean White with Green Accents */}
+
+
+
-
+
+
+
{person.name}
- {person.role}
+ {person.role.toUpperCase()}
@@ -184,7 +270,9 @@ export const PDFBusinessCard: React.FC = ({
-
+
+
+
diff --git a/scripts/gen-logo-vector.ts b/scripts/gen-logo-vector.ts
new file mode 100644
index 00000000..a5af22b3
--- /dev/null
+++ b/scripts/gen-logo-vector.ts
@@ -0,0 +1,21 @@
+import * as fs from 'fs';
+
+const svgContent = fs.readFileSync('public/logo-white.svg', 'utf8');
+const dMatches = [...svgContent.matchAll(/d="([^"]+)"/g)].map((m) => m[1]);
+
+let tsx = `import React from 'react';\nimport { Svg, G, Path } from '@react-pdf/renderer';\n\n`;
+tsx += `export const KLZLogoVector = ({ width, color }: { width: number, color: string }) => {\n`;
+tsx += ` // Original viewBox was 0 0 295 99, so height is width * 99 / 295\n`;
+tsx += ` const height = width * (99 / 295);\n`;
+tsx += ` return (\n`;
+tsx += ` \n );\n};\n`;
+
+fs.writeFileSync('lib/KLZLogoVector.tsx', tsx);
+console.log('Generated KLZLogoVector.tsx');