- Schema: add `font_color` (hex, default #000000) and `logo_object_path`
to `executive_meeting_font_settings`. Pushed via drizzle-kit.
- PDF renderer:
- Add `fontColor` to PdfFontPrefs (body cells only; header chrome
and logo intentionally ignore it to preserve branding).
- Add `rowColor` to PdfMeeting and a ROW_COLOR_FILL palette kept in
lockstep with the on-screen swatches; deliberately stop painting
the legacy `isHighlighted` overlay so the archived PDF reflects
editorial state instead of the viewer's transient cursor.
- Add optional `logo: Buffer`. Header now reserves a left-anchored
logo box and centers the title in the remaining width; bad image
bytes log + fall back to the no-logo layout instead of crashing.
- API route:
- Extend fontSettingsSchema with strict #RRGGBB regex and
/^/objects/<id>$/ regex for logoObjectPath.
- resolveFontPrefsForUser now returns { font, logoObjectPath }.
- loadLogoBytes downloads the brand asset via ObjectStorageService.
- Logo only writable on the global-scope row.
- PDF labels switched to "قائمة بأسماء حضور الاجتماعات" /
"Meeting Attendance List" per the user's printed sample.
- Frontend (executive-meetings.tsx):
- FontPrefs gains fontColor; FontSettingsResponse.global gains
logoObjectPath; DEFAULT_FONT and effectiveFont updated.
- buildFontStyle applies fontColor to on-screen rows.
- FontSettingsSection: native color picker + hex text input;
logo upload (PNG/JPEG) via @workspace/object-storage-web's
useUpload, visible only at the global scope for admins.
- Locales: AR/EN keys for fontColor + logo.{label,upload,replace,
remove,uploading,uploadFailed,globalOnly}.
- Tests: existing font-settings roundtrip extended with fontColor;
new test rejects malformed fontColor and non-/objects logo paths.
Type-check clean for api-server and tx-os; new font-settings tests
pass. Other test failures in the suite pre-date this change.