From f315ddabc69b5fb53a8fd837e6c3194fecc4806b Mon Sep 17 00:00:00 2001 From: Jason Stedwell Date: Fri, 3 Jul 2026 10:35:42 -0500 Subject: [PATCH] brand identity cleanup --- src/lib/google-drive.ts | 86 +++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/src/lib/google-drive.ts b/src/lib/google-drive.ts index 932c2f3..5064333 100644 --- a/src/lib/google-drive.ts +++ b/src/lib/google-drive.ts @@ -147,43 +147,72 @@ export function generateReportHTML(report: ReportWithRelations) { const plannedTasks = report.tasks.filter((t) => t.type === 'PLANNED'); const completedTasks = report.tasks.filter((t) => t.type === 'COMPLETED'); - // MPM brand palette - const GOLD_DARK = '#998643'; // titles on light backgrounds - const GOLD_MID = '#DCBB4F'; // accent lines, dividers + // MPM brand palette (matches the hex values used across MPM technical docs) + const GOLD_DARK = '#998643'; // document titles, section headings + const GOLD_MID = '#DCBB4F'; // accent rules / dividers const SHADE_DARK = '#232022'; // body text / table header background - const SHADE_LIGHT = '#F5F1EC'; // section panels / table header text - const OFF_WHITE = '#FAF7F2'; // alternating table rows + const SHADE_LIGHT = '#F5F1EC'; // key-column / table header text fill + const OFF_WHITE = '#FAF7F2'; // alternating data-table rows const ACCENT = '#849698'; // secondary / muted text + const BORDER = '#E7E0D5'; // hairline cell borders (warm gray) const bodyFont = "'Open Sans', Arial, sans-serif"; const headingFont = "'Montserrat', 'Open Sans', Arial, sans-serif"; - const cellStyle = `padding: 10px; border-bottom: 1px solid #E7E0D5; font-family: ${bodyFont}; font-size: 11pt; color: ${SHADE_DARK};`; - const headerStyle = `padding: 12px 10px; background-color: ${SHADE_DARK}; font-family: ${headingFont}; font-size: 11pt; font-weight: 600; text-align: left; color: ${SHADE_LIGHT};`; + const statusLabel = (report.status || 'DRAFT').charAt(0) + (report.status || 'DRAFT').slice(1).toLowerCase(); + const docRef = `WFH-${new Date(report.date).toISOString().slice(0, 10)}`; + + // Data-table cell styles + const cellStyle = `padding: 8px 12px; border: 1px solid ${BORDER}; font-family: ${bodyFont}; font-size: 10.5pt; color: ${SHADE_DARK}; vertical-align: top;`; + const headerStyle = `padding: 9px 12px; background-color: ${SHADE_DARK}; border: 1px solid ${SHADE_DARK}; font-family: ${headingFont}; font-size: 10pt; font-weight: 600; text-align: left; color: ${SHADE_LIGHT};`; + const rowBg = (i: number) => (i % 2 === 1 ? ` background-color: ${OFF_WHITE};` : ''); + + // Document Control-style key/value row + const metaKey = `width: 26%; padding: 8px 12px; background-color: ${SHADE_LIGHT}; border: 1px solid ${BORDER}; font-family: ${headingFont}; font-weight: 600; font-size: 10pt; color: ${SHADE_DARK};`; + const metaVal = `padding: 8px 12px; border: 1px solid ${BORDER}; background-color: #FFFFFF; font-size: 10.5pt; color: ${SHADE_DARK};`; + const metaRow = (k: string, v: string) => + `${k}${v}`; + + // Section label styled like the technical docs' "Document Control" heading. + const sectionLabel = (text: string) => + `

${text}

`; + const sectionHeading = (text: string) => + `

${text}

`; + + // A gold rule rendered as a filled 1-row table (survives Google Docs conversion, + // where border-bottom on headings/divs does not). + const goldRule = `
 
`; + + const emptyNote = (text: string) => + `

${text}

`; // Embed the logo inline so it survives conversion without a reachable host. const logoDataUri = getLogoDataUri(); const logoHtml = logoDataUri - ? `Message Point Media` + ? `Message Point Media` : ''; - const rowBg = (i: number) => (i % 2 === 1 ? ` background-color: ${OFF_WHITE};` : ''); - return ` - + ${logoHtml} -

WFH Daily Report

+

Message Point Media

+

WFH Daily Report

+

Daily Work-From-Home Status  |  ${escapeHtml(report.user.name)}  |  ${dateStr}

+ ${goldRule} -
-

Date: ${dateStr}

-

Employee: ${escapeHtml(report.user.name)}

-

Manager: ${escapeHtml(report.managerName || 'N/A')}

-
+ ${sectionLabel('Report Details')} + + ${metaRow('Employee', escapeHtml(report.user.name))} + ${metaRow('Date', dateStr)} + ${metaRow('Manager', escapeHtml(report.managerName || 'N/A'))} + ${metaRow('Status', statusLabel)} + ${metaRow('Reference', docRef)} +
-

Planned Tasks

+ ${sectionHeading('1. Planned Tasks')} ${plannedTasks.length > 0 ? ` - +
@@ -197,11 +226,11 @@ export function generateReportHTML(report: ReportWithRelations) { `).join('')}
Description Estimate
- ` : `

No planned tasks for today.

`} + ` : emptyNote('No planned tasks for today.')} -

Completed Tasks

+ ${sectionHeading('2. Completed Tasks')} ${completedTasks.length > 0 ? ` - +
@@ -212,18 +241,19 @@ export function generateReportHTML(report: ReportWithRelations) { return ` - + `; }).join('')}
Description Status
${escapeHtml(t.description)}${escapeHtml(t.status || 'Done')}${escapeHtml(t.status || 'Done')} ${link ? `${escapeHtml(link)}` : '-'}
- ` : `

No completed tasks reported today.

`} + ` : emptyNote('No completed tasks reported today.')} -
-

Born to Innovate. Built to Last.

-

Message Point Media · Generated automatically by the WFH Daily Report app

-
+ ${goldRule} +

Prepared by ${escapeHtml(report.user.name)}

+

Message Point Media  ·  ${docRef}  ·  Generated by the WFH Daily Report app

+

Born to Innovate. Built to Last.

+

Compelling… Affordable… Dynamic… Messaging… It’s What We Do!

`;