feat(og): v3 centered card layout with improved visual balance

Vertically center all content (badge, title, description, avatar) to
eliminate dead space. Move accent bar to top, inline badge+date row,
site name bottom-right. Bump DESIGN_VERSION to 3 for full regeneration.

Confab-Link: http://localhost:8080/sessions/5565387e-4eb5-4441-89fb-2c6347de8e0c
This commit is contained in:
Ricardo
2026-03-10 20:53:27 +01:00
parent 4adb8f0afd
commit e1aa8cb762

112
lib/og.js
View File

@@ -26,7 +26,7 @@ const WIDTH = 1200;
const HEIGHT = 630; const HEIGHT = 630;
// Card design version — bump to force full regeneration // Card design version — bump to force full regeneration
const DESIGN_VERSION = 2; const DESIGN_VERSION = 3;
const COLORS = { const COLORS = {
bg: "#ffffff", bg: "#ffffff",
@@ -208,9 +208,6 @@ function buildCard(title, description, dateStr, postType, siteName) {
const avatar = loadAvatar(); const avatar = loadAvatar();
const formattedDate = formatDate(dateStr); const formattedDate = formatDate(dateStr);
// Bottom metadata: "Note · Mar 10, 2026"
const metaParts = [postType, formattedDate].filter(Boolean).join(" \u00b7 ");
return { return {
type: "div", type: "div",
props: { props: {
@@ -222,14 +219,27 @@ function buildCard(title, description, dateStr, postType, siteName) {
backgroundColor: COLORS.bg, backgroundColor: COLORS.bg,
}, },
children: [ children: [
// Main content area // Top accent bar
{
type: "div",
props: {
style: {
width: "100%",
height: "6px",
backgroundColor: COLORS.bar,
flexShrink: 0,
},
},
},
// Main content — vertically centered
{ {
type: "div", type: "div",
props: { props: {
style: { style: {
display: "flex", display: "flex",
flex: 1, flex: 1,
padding: "60px 60px 0 60px", padding: "0 64px",
alignItems: "center",
}, },
children: [ children: [
// Left: text content // Left: text content
@@ -240,21 +250,58 @@ function buildCard(title, description, dateStr, postType, siteName) {
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
flex: 1, flex: 1,
gap: "20px", gap: "16px",
overflow: "hidden", overflow: "hidden",
paddingRight: avatar ? "40px" : "0", paddingRight: avatar ? "48px" : "0",
}, },
children: [ children: [
// Post type badge + date inline
{
type: "div",
props: {
style: {
display: "flex",
alignItems: "center",
gap: "12px",
color: COLORS.meta,
fontSize: "18px",
fontWeight: 400,
fontFamily: "Inter",
},
children: [
{
type: "span",
props: {
style: {
backgroundColor: COLORS.badge,
color: COLORS.badgeText,
fontSize: "14px",
fontWeight: 700,
fontFamily: "Inter",
padding: "4px 12px",
borderRadius: "999px",
textTransform: "uppercase",
letterSpacing: "0.05em",
},
children: postType,
},
},
formattedDate
? { type: "span", props: { children: formattedDate } }
: null,
].filter(Boolean),
},
},
// Title // Title
{ {
type: "div", type: "div",
props: { props: {
style: { style: {
color: COLORS.title, color: COLORS.title,
fontSize: "42px", fontSize: "48px",
fontWeight: 700, fontWeight: 700,
fontFamily: "Inter", fontFamily: "Inter",
lineHeight: 1.25, lineHeight: 1.2,
overflow: "hidden", overflow: "hidden",
}, },
children: truncate(title, 120), children: truncate(title, 120),
@@ -267,7 +314,7 @@ function buildCard(title, description, dateStr, postType, siteName) {
props: { props: {
style: { style: {
color: COLORS.description, color: COLORS.description,
fontSize: "24px", fontSize: "22px",
fontWeight: 400, fontWeight: 400,
fontFamily: "Inter", fontFamily: "Inter",
lineHeight: 1.4, lineHeight: 1.4,
@@ -288,17 +335,16 @@ function buildCard(title, description, dateStr, postType, siteName) {
style: { style: {
display: "flex", display: "flex",
flexShrink: 0, flexShrink: 0,
alignItems: "flex-start",
}, },
children: [ children: [
{ {
type: "img", type: "img",
props: { props: {
src: avatar, src: avatar,
width: 120, width: 128,
height: 120, height: 128,
style: { style: {
borderRadius: "12px", borderRadius: "16px",
border: `2px solid ${COLORS.border}`, border: `2px solid ${COLORS.border}`,
}, },
}, },
@@ -310,37 +356,23 @@ function buildCard(title, description, dateStr, postType, siteName) {
].filter(Boolean), ].filter(Boolean),
}, },
}, },
// Bottom metadata row // Footer: site name
{ {
type: "div", type: "div",
props: { props: {
style: { style: {
display: "flex", display: "flex",
justifyContent: "space-between", justifyContent: "flex-end",
alignItems: "center", alignItems: "center",
padding: "0 60px 40px 60px", padding: "0 64px 32px 64px",
}, },
children: [ children: [
// Left: post type · date
{ {
type: "div", type: "div",
props: { props: {
style: { style: {
color: COLORS.meta, color: "#8b949e",
fontSize: "20px", fontSize: "18px",
fontWeight: 400,
fontFamily: "Inter",
},
children: metaParts,
},
},
// Right: site name
{
type: "div",
props: {
style: {
color: COLORS.meta,
fontSize: "20px",
fontWeight: 400, fontWeight: 400,
fontFamily: "Inter", fontFamily: "Inter",
}, },
@@ -350,18 +382,6 @@ function buildCard(title, description, dateStr, postType, siteName) {
], ],
}, },
}, },
// Bottom accent bar
{
type: "div",
props: {
style: {
width: "100%",
height: "6px",
backgroundColor: COLORS.bar,
flexShrink: 0,
},
},
},
], ],
}, },
}; };