import { escapeHtml, getYear, renderFooterMetaBlock, renderSignatoryBlock, SIGNATURE_IMAGE_STYLES, type TemplateRenderer } from './shared'; export const renderPoster: TemplateRenderer = ({ design, data }) => { const accent = design.accentColor; const subtitle = design.subtitle ?? ''; const description = design.descriptionOverride || data.courseDescription; const [signatoryOne, signatoryTwo] = design.signatories; const [firstTitleWord, ...restTitleWords] = data.courseName.split(' '); const titleEmphasis = restTitleWords.join(' '); const body = `
${escapeHtml(data.orgName)} ${escapeHtml(data.certificateId)} / ${escapeHtml(data.date)}
${escapeHtml(firstTitleWord || 'Award')} ${escapeHtml(titleEmphasis)}
${escapeHtml(subtitle)}
Awarded To
${escapeHtml(data.recipientName)}
${escapeHtml(description)}
${renderSignatoryBlock(signatoryOne, { nameClass: 'v', roleClass: 'k', roleFirst: true })} ${renderSignatoryBlock(signatoryTwo, { nameClass: 'v', roleClass: 'k', roleFirst: true })} ${renderFooterMetaBlock('Issued', data.date, { labelClass: 'k', valueClass: 'v' })}
${getYear(data.date)}
`; const styles = ` .t-poster { background: #fef2dc; color: #1a1a1a; padding: 0; font-family: 'Space Grotesk', sans-serif; overflow: hidden; } .t-poster .blob { position: absolute; width: 550px; height: 550px; border-radius: 50%; filter: blur(2px); opacity: 0.95; } .t-poster .blob-1 { background: ${accent}; top: -180px; right: -120px; } .t-poster .blob-2 { background: #1e3a8a; bottom: -200px; left: -150px; width: 480px; height: 480px; } .t-poster .blob-3 { background: #fbbf24; top: 40%; left: 55%; width: 200px; height: 200px; } .t-poster .content { position: relative; z-index: 2; height: 100%; padding: 50px 55px; display: flex; flex-direction: column; } .t-poster .top { display: flex; justify-content: space-between; font-family: 'JetBrains Mono', monospace; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 30px; } .t-poster .top .pill { background: ${accent}; color: #fef2dc; padding: 5px 12px; border-radius: 100px; } .t-poster .title { font-family: 'Playfair Display', serif; font-size: 140px; font-weight: 900; line-height: 0.85; letter-spacing: -0.04em; color: #1a1a1a; } .t-poster .title em { font-style: italic; font-weight: 400; color: ${accent}; } .t-poster .of { font-family: 'Playfair Display', serif; font-size: 62px; font-style: italic; font-weight: 400; line-height: 1; margin-top: -4px; color: #1a1a1a; } .t-poster .recipient-area { margin-top: 40px; background: ${accent}; color: #fef2dc; padding: 24px 30px; align-self: flex-start; max-width: 75%; transform: rotate(-1deg); box-shadow: 8px 8px 0 #1a1a1a; } .t-poster .recipient-area .lbl { font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: 0.22em; color: #fef2dc; opacity: 0.8; text-transform: uppercase; margin-bottom: 6px; } .t-poster .recipient { font-family: 'Playfair Display', serif; font-size: 54px; font-weight: 700; line-height: 1; letter-spacing: -0.02em; } .t-poster .description { font-size: 15px; line-height: 1.55; margin-top: 20px; max-width: 580px; color: #1a1a1a; font-weight: 500; } .t-poster .bottom { margin-top: auto; display: grid; grid-template-columns: 1fr 1fr 1fr; align-items: end; gap: 24px; border-top: 2px solid #1a1a1a; padding-top: 18px; font-family: 'JetBrains Mono', monospace; } .t-poster .bottom .sig-content, .t-poster .bottom .sig-text { align-items: flex-start; text-align: left; } .t-poster .bottom .sig-img-slot { justify-content: flex-start; } .t-poster .bottom .k { font-size: 9px; letter-spacing: 0.2em; text-transform: uppercase; color: #666; margin-bottom: 3px; } .t-poster .bottom .v { font-family: 'Playfair Display', serif; font-size: 22px; font-weight: 700; color: #1a1a1a; } .t-poster .corner-num { position: absolute; bottom: 36px; right: 50px; font-family: 'Playfair Display', serif; font-size: 80px; font-weight: 900; font-style: italic; color: ${accent}; z-index: 3; line-height: 0.8; } ${SIGNATURE_IMAGE_STYLES} `; return { body, styles }; };