AI Real Estate Marketing Virtual Assistant: Automating Property Listings

Executive Summary
Real estate agents spent 45 minutes per property on manual listing content, delaying publication and creating inconsistent quality. Our AI Real Estate Marketing Virtual Assistant now extracts data automatically, generates SEO-rich property descriptions and social content, and enables one-click approval via Slack. Agents save 85% of their listing creation time while publishing higher-quality content faster.
Problem Statement
Real estate agents faced a daily content bottleneck that consumed valuable selling time. Each property required 45 minutes researching school scores, commute times, and amenities—totaling 7.5 hours monthly for agents managing just 10 listings. This administrative burden caused significant listing publication delays, inconsistent brand quality, and limited scalability during high-volume periods. For new real estate agents especially, this directly reduced time available for lead generation and client relationships.

Solution Overview
The AI Real Estate Marketing Virtual Assistant streamlines the entire process through automated data gathering and intelligent content creation. When new listings appear in HubSpot, the assistant automatically extracts property information from Ofsted, WalkScore, and Google Places APIs. Using GPT-4o, it creates comprehensive property descriptions optimized for search visibility, tailored social media content, and strategic meta tags to enhance organic traffic.
The workflow operates seamlessly: an agent creates a property record in HubSpot, the assistant generates content, the agent approves or edits via Slack, and the approved content instantly publishes to the CMS. Built on GPT-4o with LangChain orchestration and Pinecone for contextual memory, the system integrates directly with essential real estate data sources.
Implementation Process
Implementation focused on frictionless integration with existing workflows. The assistant operates through Slack—a platform agents already use daily—requiring minimal training and immediate productivity gains. Custom real estate software development connected the assistant to authoritative data providers, eliminating manual research while preserving agent final approval authority for quality control.
The technical foundation combines a Python backend with FastAPI, a React-based Slack UI, and PostgreSQL database for persistent context across interactions, creating a robust real estate document management solution that enhances rather than disrupts existing agent workflows.

Results and Benefits
The AI assistant reduced listing creation time by 85% (from 45 minutes to just 5-10 minutes) by eliminating manual research and automating content generation. This enabled same-day listing publication versus the previous one-day delay, significantly improving property visibility during peak buyer interest periods.
For real estate agents, this meant redirected time toward lead generation and client relationships, consistent high-quality content regardless of personal writing ability, and higher listing capacity without increased workload. Brokerages benefited from a faster property-to-market pipeline, uniform brand voice across all marketing materials, enhanced scalability during market fluctuations, and improved document management accuracy.
Conclusion
This virtual assistant for real estate agents transforms a significant daily burden into a brief review activity while simultaneously improving content quality and consistency. By focusing agents on relationship-building rather than administrative tasks, the solution delivers tangible value through faster, more consistent property listings.
Future plans include integration with real estate wholesaling software functionality, expansion to video script generation for property tours, and enhanced analytics for listing performance optimization. The human-AI collaboration model demonstrates how intelligent automation can handle repetitive tasks while preserving human expertise where it adds the most value.
/* ============================================================
WEBFLOW CMS ARTICLE PAGE — ENHANCED STYLESHEET
Mobile-first | Medium/HubSpot-inspired | SaaS-grade
============================================================ */
/* ─── DESIGN TOKENS ─────────────────────────────────────── */
:root {
/* Typography */
--font-display: 'Lora', 'Georgia', serif;
--font-body: 'Source Serif 4', 'Georgia', serif;
--font-ui: 'DM Sans', 'Helvetica Neue', sans-serif;
/* Scale (mobile-first) */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1.0625rem; /* 17px — optimal reading size */
--text-lg: 1.1875rem; /* 19px */
--text-xl: 1.375rem; /* 22px */
--text-2xl: 1.625rem; /* 26px */
--text-3xl: 2rem; /* 32px */
--text-4xl: 2.5rem; /* 40px */
--text-5xl: 3.25rem; /* 52px */
/* Line heights */
--leading-tight: 1.2;
--leading-snug: 1.4;
--leading-normal: 1.65;
--leading-relaxed: 1.8;
/* Colors */
--color-ink: #1a1a2e;
--color-ink-2: #2d2d44;
--color-ink-3: #4a4a6a;
--color-muted: #6b6b8a;
--color-subtle: #9898b2;
--color-border: #e4e4f0;
--color-border-2: #d0d0e8;
--color-surface: #fafafa;
--color-bg: #ffffff;
/* Brand accent */
--color-accent: #2563eb;
--color-accent-2: #1d4ed8;
--color-accent-3: #dbeafe;
--color-accent-4: #eff6ff;
/* Highlight */
--color-highlight: #f59e0b;
--color-highlight-2: #fef3c7;
/* Layout */
--content-width: 740px;
--wide-width: 900px;
--full-width: 1200px;
/* Spacing */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--space-12: 3rem;
--space-16: 4rem;
--space-20: 5rem;
--space-24: 6rem;
/* Radii */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-2xl: 24px;
/* Shadows */
--shadow-sm: 0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04);
--shadow-md: 0 4px 16px rgba(0,0,0,.07), 0 1px 4px rgba(0,0,0,.04);
--shadow-lg: 0 8px 32px rgba(0,0,0,.10), 0 2px 8px rgba(0,0,0,.05);
--shadow-xl: 0 20px 60px rgba(0,0,0,.12), 0 4px 16px rgba(0,0,0,.06);
/* Transitions */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in: cubic-bezier(0.7, 0, 0.84, 0);
--duration: 200ms;
}
/* ─── RESET & BASE ───────────────────────────────────────── */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 16px;
-webkit-text-size-adjust: 100%;
scroll-behavior: smooth;
}
body {
font-family: var(--font-body);
font-size: var(--text-base);
line-height: var(--leading-normal);
color: var(--color-ink);
background: var(--color-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
img, video, svg {
max-width: 100%;
height: auto;
display: block;
}
/* ─── LAYOUT CONTAINER ───────────────────────────────────── */
/* Webflow CMS wrapper — add .article-wrapper or target your top-level div */
.article-wrapper,
.w-container,
[class*="post-container"],
[class*="article-container"],
[class*="blog-container"] {
max-width: 100%;
padding-left: var(--space-5);
padding-right: var(--space-5);
}
/* Core article content column */
.article-content,
.post-body,
.blog-post-content,
.rich-text-block,
.w-richtext {
width: 100%;
max-width: var(--content-width);
margin-left: auto;
margin-right: auto;
}
/* ─── ARTICLE HEADER ─────────────────────────────────────── */
.article-header,
.post-header,
[class*="blog-header"],
[class*="post-header"] {
max-width: var(--content-width);
margin: 0 auto var(--space-8);
padding-top: var(--space-10);
}
/* Category / Tag pill */
.article-category,
.post-category,
.blog-category,
[class*="category-label"],
[class*="post-tag"] {
display: inline-flex;
align-items: center;
font-family: var(--font-ui);
font-size: var(--text-xs);
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-accent);
background: var(--color-accent-4);
border: 1px solid var(--color-accent-3);
padding: var(--space-1) var(--space-3);
border-radius: 100px;
margin-bottom: var(--space-5);
text-decoration: none;
transition: background var(--duration) var(--ease-out),
color var(--duration) var(--ease-out);
}
.article-category:hover,
.post-category:hover {
background: var(--color-accent);
color: #fff;
}
/* Article main headline */
.article-title,
.post-title,
[class*="blog-title"],
[class*="post-heading-main"] {
font-family: var(--font-display);
font-size: var(--text-3xl);
font-weight: 700;
line-height: var(--leading-snug);
color: var(--color-ink);
letter-spacing: -0.02em;
margin-bottom: var(--space-5);
}
/* Article subtitle / excerpt */
.article-subtitle,
.post-subtitle,
[class*="post-excerpt"],
[class*="article-description"] {
font-family: var(--font-body);
font-size: var(--text-lg);
line-height: var(--leading-relaxed);
color: var(--color-muted);
margin-bottom: var(--space-6);
font-style: italic;
}
/* ─── AUTHOR / META BAR ──────────────────────────────────── */
.article-meta,
.post-meta,
[class*="author-meta"],
[class*="post-info"] {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-3);
padding: var(--space-4) 0;
border-top: 1px solid var(--color-border);
border-bottom: 1px solid var(--color-border);
margin-bottom: var(--space-8);
font-family: var(--font-ui);
}
.author-avatar,
[class*="author-image"],
[class*="author-photo"] {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
border: 2px solid var(--color-border);
}
.author-name,
[class*="author-name"] {
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-ink-2);
}
.post-date,
.article-date,
[class*="post-date"],
[class*="publish-date"] {
font-size: var(--text-sm);
color: var(--color-muted);
}
.read-time,
[class*="read-time"],
[class*="reading-time"] {
font-size: var(--text-sm);
color: var(--color-subtle);
}
/* Dot separator */
.meta-dot {
width: 3px;
height: 3px;
border-radius: 50%;
background: var(--color-border-2);
flex-shrink: 0;
}
/* ─── FEATURED IMAGE ─────────────────────────────────────── */
.article-featured-image,
.post-featured-image,
[class*="featured-image"],
[class*="hero-image"],
[class*="post-thumbnail"] {
width: 100%;
max-width: var(--wide-width);
margin: 0 auto var(--space-10);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-lg);
aspect-ratio: 16 / 9;
}
.article-featured-image img,
.post-featured-image img,
[class*="featured-image"] img,
[class*="hero-image"] img,
[class*="post-thumbnail"] img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
transition: transform 0.6s var(--ease-out);
}
.article-featured-image:hover img,
.post-featured-image:hover img {
transform: scale(1.02);
}
/* ─── RICH TEXT / BODY CONTENT ───────────────────────────── */
.w-richtext,
.rich-text-block,
.article-body,
.post-body-content,
[class*="article-body"],
[class*="post-content"] {
/* Global text defaults */
font-family: var(--font-body);
font-size: var(--text-base);
line-height: var(--leading-relaxed);
color: var(--color-ink-2);
}
/* --- Headings --- */
.w-richtext h1,
.w-richtext h2,
.w-richtext h3,
.w-richtext h4,
.w-richtext h5,
.w-richtext h6,
[class*="article-body"] h1,
[class*="article-body"] h2,
[class*="article-body"] h3,
[class*="article-body"] h4,
[class*="article-body"] h5,
[class*="article-body"] h6 {
font-family: var(--font-display);
font-weight: 700;
line-height: var(--leading-tight);
color: var(--color-ink);
letter-spacing: -0.015em;
margin-top: var(--space-12);
margin-bottom: var(--space-4);
}
.w-richtext h1 { font-size: var(--text-3xl); }
.w-richtext h2 { font-size: var(--text-2xl); }
.w-richtext h3 { font-size: var(--text-xl); }
.w-richtext h4 { font-size: var(--text-lg); font-weight: 600; }
.w-richtext h5 { font-size: var(--text-base); font-weight: 600; }
.w-richtext h6 { font-size: var(--text-sm); font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-muted); }
/* First heading after intro — less top space */
.w-richtext > h2:first-child,
.w-richtext > h3:first-child {
margin-top: 0;
}
/* --- Paragraphs --- */
.w-richtext p,
[class*="article-body"] p {
margin-bottom: var(--space-6);
font-size: var(--text-base);
line-height: var(--leading-relaxed);
color: var(--color-ink-2);
}
.w-richtext p:last-child { margin-bottom: 0; }
/* Lead paragraph */
.w-richtext p.lead,
.w-richtext > p:first-of-type {
font-size: var(--text-lg);
color: var(--color-ink-3);
line-height: 1.75;
}
/* --- Links --- */
.w-richtext a,
[class*="article-body"] a {
color: var(--color-accent);
text-decoration: underline;
text-decoration-color: var(--color-accent-3);
text-underline-offset: 3px;
transition: color var(--duration), text-decoration-color var(--duration);
}
.w-richtext a:hover {
color: var(--color-accent-2);
text-decoration-color: var(--color-accent-2);
}
/* --- Strong / Em --- */
.w-richtext strong { font-weight: 700; color: var(--color-ink); }
.w-richtext em { font-style: italic; color: var(--color-ink-3); }
/* --- Ordered & Unordered Lists --- */
.w-richtext ul,
.w-richtext ol,
[class*="article-body"] ul,
[class*="article-body"] ol {
margin: var(--space-2) 0 var(--space-6) var(--space-6);
padding: 0;
}
.w-richtext li,
[class*="article-body"] li {
margin-bottom: var(--space-2);
line-height: var(--leading-relaxed);
color: var(--color-ink-2);
padding-left: var(--space-2);
}
.w-richtext ul { list-style: none; }
.w-richtext ul li::before {
content: '';
display: inline-block;
width: 6px;
height: 6px;
background: var(--color-accent);
border-radius: 50%;
margin-right: var(--space-3);
margin-left: calc(-1 * var(--space-5));
vertical-align: middle;
flex-shrink: 0;
}
.w-richtext ol { list-style: decimal; }
.w-richtext ol li::marker {
color: var(--color-accent);
font-weight: 700;
font-family: var(--font-ui);
}
/* Nested lists */
.w-richtext ul ul,
.w-richtext ol ol,
.w-richtext ul ol,
.w-richtext ol ul {
margin-top: var(--space-2);
margin-bottom: 0;
}
/* --- Blockquote --- */
.w-richtext blockquote,
[class*="article-body"] blockquote {
position: relative;
margin: var(--space-10) 0;
padding: var(--space-6) var(--space-8);
background: var(--color-accent-4);
border-left: 4px solid var(--color-accent);
border-radius: 0 var(--radius-md) var(--radius-md) 0;
font-size: var(--text-xl);
font-style: italic;
line-height: var(--leading-snug);
color: var(--color-ink-2);
}
.w-richtext blockquote::before {
content: '\201C';
position: absolute;
top: -0.1em;
left: var(--space-4);
font-size: 4rem;
color: var(--color-accent-3);
font-family: var(--font-display);
line-height: 1;
}
.w-richtext blockquote p {
margin-bottom: 0;
font-size: inherit;
}
.w-richtext blockquote cite,
.w-richtext blockquote footer {
display: block;
margin-top: var(--space-4);
font-size: var(--text-sm);
font-style: normal;
font-family: var(--font-ui);
color: var(--color-muted);
font-weight: 600;
}
/* --- Inline Code --- */
.w-richtext code,
[class*="article-body"] code {
font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
font-size: 0.875em;
background: var(--color-surface);
border: 1px solid var(--color-border);
color: #d6336c;
padding: 0.1em 0.4em;
border-radius: var(--radius-sm);
white-space: nowrap;
}
/* --- Code Block --- */
.w-richtext pre,
[class*="article-body"] pre {
margin: var(--space-8) 0;
padding: var(--space-6);
background: #1a1a2e;
border-radius: var(--radius-lg);
overflow-x: auto;
box-shadow: var(--shadow-md);
position: relative;
}
.w-richtext pre code {
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: var(--text-sm);
line-height: 1.7;
color: #e2e8f0;
background: none;
border: none;
padding: 0;
white-space: pre;
}
/* --- Horizontal Rule --- */
.w-richtext hr,
[class*="article-body"] hr {
border: none;
height: 1px;
background: linear-gradient(
to right,
transparent,
var(--color-border-2) 20%,
var(--color-border-2) 80%,
transparent
);
margin: var(--space-12) auto;
max-width: 200px;
}
/* --- Inline Images in Body --- */
.w-richtext figure,
[class*="article-body"] figure {
margin: var(--space-10) 0;
}
.w-richtext figure img,
[class*="article-body"] figure img {
width: 100%;
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
}
.w-richtext figure figcaption,
[class*="article-body"] figure figcaption {
margin-top: var(--space-3);
text-align: center;
font-family: var(--font-ui);
font-size: var(--text-sm);
color: var(--color-subtle);
font-style: italic;
}
/* Standalone images (no figure wrapper) */
.w-richtext img,
[class*="article-body"] img {
border-radius: var(--radius-lg);
box-shadow: var(--shadow-md);
margin: var(--space-8) auto;
}
/* --- Table --- */
.w-richtext table,
[class*="article-body"] table {
width: 100%;
margin: var(--space-8) 0;
border-collapse: collapse;
font-family: var(--font-ui);
font-size: var(--text-sm);
overflow: hidden;
border-radius: var(--radius-lg);
box-shadow: var(--shadow-sm);
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.w-richtext th {
background: var(--color-ink);
color: #fff;
font-weight: 600;
padding: var(--space-3) var(--space-4);
text-align: left;
letter-spacing: 0.03em;
}
.w-richtext td {
padding: var(--space-3) var(--space-4);
border-bottom: 1px solid var(--color-border);
color: var(--color-ink-2);
}
.w-richtext tr:last-child td { border-bottom: none; }
.w-richtext tr:nth-child(even) td { background: var(--color-surface); }
.w-richtext tr:hover td { background: var(--color-accent-4); }
/* ─── PULL QUOTE / CALLOUT ───────────────────────────────── */
.callout,
.info-box,
.tip-box,
[class*="callout"],
[class*="tip-box"],
[class*="info-block"] {
display: flex;
gap: var(--space-4);
margin: var(--space-8) 0;
padding: var(--space-5) var(--space-6);
background: var(--color-highlight-2);
border: 1px solid #fcd34d;
border-left: 4px solid var(--color-highlight);
border-radius: var(--radius-lg);
font-family: var(--font-ui);
font-size: var(--text-sm);
line-height: var(--leading-normal);
color: #78350f;
}
/* ─── CTA BUTTON ─────────────────────────────────────────── */
.w-button,
.cta-button,
.btn,
[class*="btn-primary"],
[class*="cta-btn"],
[class*="article-cta"] {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
font-family: var(--font-ui);
font-size: var(--text-sm);
font-weight: 600;
line-height: 1;
letter-spacing: 0.02em;
padding: 0.8125rem 1.625rem;
background: var(--color-accent);
color: #fff;
border: 2px solid transparent;
border-radius: var(--radius-md);
cursor: pointer;
text-decoration: none;
transition:
background var(--duration) var(--ease-out),
transform var(--duration) var(--ease-out),
box-shadow var(--duration) var(--ease-out);
white-space: nowrap;
-webkit-user-select: none;
user-select: none;
}
.w-button:hover,
.cta-button:hover,
.btn:hover {
background: var(--color-accent-2);
transform: translateY(-1px);
box-shadow: 0 8px 24px rgba(37, 99, 235, 0.3);
color: #fff;
}
.w-button:active,
.cta-button:active {
transform: translateY(0);
box-shadow: none;
}
/* Secondary / Ghost variant */
.btn-secondary,
[class*="btn-secondary"],
[class*="btn-outline"] {
background: transparent;
color: var(--color-accent);
border-color: var(--color-accent);
}
.btn-secondary:hover {
background: var(--color-accent-4);
transform: translateY(-1px);
box-shadow: none;
}
/* Full-width CTA block */
.cta-block,
[class*="cta-block"],
[class*="article-cta-section"] {
margin: var(--space-12) 0;
padding: var(--space-10) var(--space-8);
background: linear-gradient(135deg, var(--color-ink) 0%, var(--color-ink-2) 100%);
border-radius: var(--radius-xl);
text-align: center;
box-shadow: var(--shadow-xl);
}
.cta-block h2,
.cta-block h3 {
font-family: var(--font-display);
color: #fff;
font-size: var(--text-2xl);
margin-bottom: var(--space-4);
}
.cta-block p {
color: rgba(255,255,255,.7);
font-size: var(--text-base);
margin-bottom: var(--space-6);
font-family: var(--font-ui);
}
/* ─── TAGS / TOPICS ROW ──────────────────────────────────── */
.article-tags,
.post-tags,
[class*="tag-list"],
[class*="article-topics"] {
display: flex;
flex-wrap: wrap;
gap: var(--space-2);
margin-top: var(--space-10);
padding-top: var(--space-6);
border-top: 1px solid var(--color-border);
}
.tag,
[class*="tag-item"],
[class*="topic-pill"] {
font-family: var(--font-ui);
font-size: var(--text-xs);
font-weight: 500;
color: var(--color-ink-3);
background: var(--color-surface);
border: 1px solid var(--color-border);
padding: var(--space-1) var(--space-3);
border-radius: 100px;
text-decoration: none;
transition:
background var(--duration),
border-color var(--duration),
color var(--duration);
}
.tag:hover {
background: var(--color-accent-4);
border-color: var(--color-accent-3);
color: var(--color-accent);
}
/* ─── SHARE BAR ──────────────────────────────────────────── */
.share-bar,
[class*="share-bar"],
[class*="social-share"] {
display: flex;
align-items: center;
gap: var(--space-3);
flex-wrap: wrap;
margin-top: var(--space-8);
padding: var(--space-5) var(--space-6);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
font-family: var(--font-ui);
}
.share-label {
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-muted);
margin-right: var(--space-2);
}
.share-btn,
[class*="share-btn"] {
display: inline-flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
font-weight: 500;
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-md);
text-decoration: none;
transition: background var(--duration), transform var(--duration);
}
.share-btn:hover { transform: translateY(-1px); }
/* ─── AUTHOR BIO CARD ────────────────────────────────────── */
.author-bio,
[class*="author-bio"],
[class*="author-card"],
[class*="writer-bio"] {
display: flex;
gap: var(--space-5);
align-items: flex-start;
margin-top: var(--space-12);
padding: var(--space-6);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-sm);
}
.author-bio-avatar,
[class*="author-bio"] img,
[class*="author-card"] img:first-child {
width: 64px;
height: 64px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
border: 3px solid var(--color-border);
}
.author-bio-name {
font-family: var(--font-ui);
font-size: var(--text-base);
font-weight: 700;
color: var(--color-ink);
margin-bottom: var(--space-1);
}
.author-bio-role {
font-family: var(--font-ui);
font-size: var(--text-sm);
color: var(--color-accent);
font-weight: 500;
margin-bottom: var(--space-3);
}
.author-bio-text {
font-size: var(--text-sm);
line-height: var(--leading-normal);
color: var(--color-ink-3);
}
/* ─── RELATED POSTS GRID ─────────────────────────────────── */
.related-posts,
[class*="related-posts"],
[class*="more-articles"],
[class*="related-articles"] {
margin-top: var(--space-16);
padding-top: var(--space-10);
border-top: 1px solid var(--color-border);
}
.related-posts-title,
[class*="related-heading"] {
font-family: var(--font-display);
font-size: var(--text-2xl);
font-weight: 700;
color: var(--color-ink);
margin-bottom: var(--space-8);
}
.related-posts-grid,
[class*="related-grid"] {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-6);
}
.related-post-card,
[class*="related-card"],
[class*="article-card"] {
background: var(--color-bg);
border: 1px solid var(--color-border);
border-radius: var(--radius-xl);
overflow: hidden;
text-decoration: none;
transition:
transform var(--duration) var(--ease-out),
box-shadow var(--duration) var(--ease-out);
display: block;
}
.related-post-card:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-lg);
}
.related-post-image img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
display: block;
transition: transform 0.4s var(--ease-out);
}
.related-post-card:hover .related-post-image img {
transform: scale(1.04);
}
.related-post-body {
padding: var(--space-5);
}
.related-post-category {
font-family: var(--font-ui);
font-size: var(--text-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--color-accent);
margin-bottom: var(--space-2);
}
.related-post-title {
font-family: var(--font-display);
font-size: var(--text-lg);
font-weight: 700;
color: var(--color-ink);
line-height: var(--leading-snug);
margin-bottom: var(--space-2);
}
.related-post-excerpt {
font-size: var(--text-sm);
color: var(--color-muted);
line-height: var(--leading-normal);
}
/* ─── PROGRESS BAR ───────────────────────────────────────── */
.reading-progress,
[class*="reading-progress"],
[class*="progress-bar"] {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: linear-gradient(90deg, var(--color-accent), #818cf8);
border-radius: 0 100px 100px 0;
z-index: 9999;
transition: width 0.1s linear;
}
/* ─── TABLE OF CONTENTS ──────────────────────────────────── */
.toc,
[class*="table-of-contents"],
[class*="toc-block"] {
margin: var(--space-8) 0;
padding: var(--space-6);
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: var(--radius-xl);
}
.toc-title {
font-family: var(--font-ui);
font-size: var(--text-sm);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-muted);
margin-bottom: var(--space-4);
}
.toc ol,
.toc ul {
margin: 0;
padding-left: var(--space-5);
}
.toc li { margin-bottom: var(--space-2); }
.toc a {
font-family: var(--font-ui);
font-size: var(--text-sm);
color: var(--color-accent);
text-decoration: none;
transition: color var(--duration);
}
.toc a:hover { color: var(--color-accent-2); text-decoration: underline; }
/* ─── STICKY SIDEBAR (optional) ─────────────────────────── */
.article-sidebar,
[class*="article-sidebar"],
[class*="post-sidebar"] {
display: none; /* Hidden on mobile, shown on large screens */
}
/* ─── BREADCRUMBS ────────────────────────────────────────── */
.breadcrumbs,
[class*="breadcrumbs"],
[class*="breadcrumb"] {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: var(--space-2);
font-family: var(--font-ui);
font-size: var(--text-sm);
color: var(--color-muted);
margin-bottom: var(--space-5);
}
.breadcrumbs a {
color: var(--color-muted);
text-decoration: none;
transition: color var(--duration);
}
.breadcrumbs a:hover { color: var(--color-accent); }
.breadcrumbs-sep { color: var(--color-border-2); }
/* ─── NEWSLETTER / SUBSCRIBE BLOCK ──────────────────────── */
.newsletter-block,
[class*="newsletter"],
[class*="subscribe-block"] {
margin: var(--space-12) 0;
padding: var(--space-8) var(--space-6);
background: linear-gradient(145deg, var(--color-accent-4) 0%, #f0f9ff 100%);
border: 1px solid var(--color-accent-3);
border-radius: var(--radius-2xl);
text-align: center;
}
.newsletter-block h3 {
font-family: var(--font-display);
font-size: var(--text-xl);
color: var(--color-ink);
margin-bottom: var(--space-2);
}
.newsletter-block p {
font-size: var(--text-sm);
color: var(--color-muted);
font-family: var(--font-ui);
margin-bottom: var(--space-5);
}
.newsletter-form,
[class*="subscribe-form"] {
display: flex;
gap: var(--space-2);
max-width: 420px;
margin: 0 auto;
flex-wrap: wrap;
}
.newsletter-form input[type="email"],
[class*="email-input"] {
flex: 1;
min-width: 0;
font-family: var(--font-ui);
font-size: var(--text-sm);
padding: 0.75rem 1rem;
background: #fff;
border: 1.5px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-ink);
outline: none;
transition: border-color var(--duration);
}
.newsletter-form input[type="email"]:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 3px rgba(37,99,235,.12);
}
/* ─── WEBFLOW SPECIFIC OVERRIDES ─────────────────────────── */
/* Reset Webflow's aggressive defaults */
.w-richtext figure.w-richtext-align-center {
margin-left: auto;
margin-right: auto;
}
.w-richtext figure.w-richtext-align-fullwidth {
max-width: 100%;
margin-left: calc(-1 * var(--space-5));
margin-right: calc(-1 * var(--space-5));
border-radius: 0;
}
.w-richtext figure.w-richtext-align-fullwidth img {
border-radius: 0;
}
/* Webflow collection list */
.w-dyn-list { width: 100%; }
.w-dyn-item { display: block; }
/* Fix Webflow default link underlines in rich text */
.w-richtext a { text-decoration: underline; }
/* ============================================================
RESPONSIVE — TABLET (≥ 640px)
============================================================ */
@media (min-width: 640px) {
:root {
--text-base: 1.125rem; /* 18px */
--text-lg: 1.25rem; /* 20px */
--text-xl: 1.5rem; /* 24px */
--text-2xl: 1.875rem; /* 30px */
--text-3xl: 2.25rem; /* 36px */
}
.article-wrapper,
.w-container {
padding-left: var(--space-8);
padding-right: var(--space-8);
}
.article-title,
.post-title {
font-size: var(--text-4xl);
}
.related-posts-grid,
[class*="related-grid"] {
grid-template-columns: repeat(2, 1fr);
}
.newsletter-form {
flex-wrap: nowrap;
}
}
/* ============================================================
RESPONSIVE — DESKTOP (≥ 768px)
============================================================ */
@media (min-width: 768px) {
.article-wrapper,
.w-container {
padding-left: var(--space-10);
padding-right: var(--space-10);
}
.article-header,
.post-header {
padding-top: var(--space-16);
margin-bottom: var(--space-10);
}
.article-featured-image,
.post-featured-image {
border-radius: var(--radius-xl);
}
.author-bio {
padding: var(--space-8);
}
}
/* ============================================================
RESPONSIVE — LARGE DESKTOP (≥ 1024px)
============================================================ */
@media (min-width: 1024px) {
:root {
--text-base: 1.125rem;
--text-3xl: 2.5rem;
--text-4xl: 3rem;
--text-5xl: 3.75rem;
}
.article-wrapper,
.w-container {
max-width: var(--full-width);
margin-left: auto;
margin-right: auto;
padding-left: var(--space-12);
padding-right: var(--space-12);
}
/* Two-column layout with sidebar */
.article-layout,
[class*="article-layout"],
[class*="post-layout"] {
display: grid;
grid-template-columns: var(--content-width) 1fr;
gap: var(--space-16);
align-items: start;
}
.article-sidebar,
[class*="article-sidebar"] {
display: block;
position: sticky;
top: var(--space-8);
}
.article-title,
.post-title {
font-size: var(--text-5xl);
}
.related-posts-grid {
grid-template-columns: repeat(3, 1fr);
}
.w-richtext h2 { font-size: var(--text-3xl); }
.w-richtext h3 { font-size: var(--text-2xl); }
.w-richtext h4 { font-size: var(--text-xl); }
}
/* ============================================================
RESPONSIVE — XL DESKTOP (≥ 1280px)
============================================================ */
@media (min-width: 1280px) {
.article-wrapper,
.w-container {
padding-left: var(--space-16);
padding-right: var(--space-16);
}
}
/* ─── NO HORIZONTAL SCROLL GUARD ────────────────────────── */
html, body {
max-width: 100%;
overflow-x: hidden;
}
/* Prevent wide tables / code from breaking layout */
.w-richtext *,
[class*="article-body"] * {
max-width: 100%;
}
.w-richtext pre {
white-space: pre;
overflow-x: auto;
}
/* ─── FOCUS / ACCESSIBILITY ──────────────────────────────── */
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 3px;
border-radius: var(--radius-sm);
}
/* ─── PRINT ──────────────────────────────────────────────── */
@media print {
.share-bar,
.reading-progress,
.newsletter-block,
.article-sidebar,
.related-posts { display: none !important; }
body {
font-size: 12pt;
color: #000;
}
.w-richtext {
max-width: 100%;
}
.w-richtext a::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #666;
}
}
/* ─── REDUCED MOTION ─────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* ─── DARK MODE ──────────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
:root {
--color-ink: #f0f0f8;
--color-ink-2: #d8d8ec;
--color-ink-3: #b0b0cc;
--color-muted: #8888a8;
--color-subtle: #6666a0;
--color-border: #2a2a40;
--color-border-2: #363650;
--color-surface: #131320;
--color-bg: #0d0d1a;
--color-accent: #60a5fa;
--color-accent-2: #93c5fd;
--color-accent-3: #1e3a6e;
--color-accent-4: #0f1e38;
--shadow-sm: 0 1px 3px rgba(0,0,0,.4);
--shadow-md: 0 4px 16px rgba(0,0,0,.5);
--shadow-lg: 0 8px 32px rgba(0,0,0,.6);
--shadow-xl: 0 20px 60px rgba(0,0,0,.7);
}
.w-richtext code { color: #f472b6; }
.w-richtext pre { background: #0a0a18; }
.newsletter-block {
background: linear-gradient(145deg, var(--color-accent-4), #0a1628);
}
.cta-block {
background: linear-gradient(135deg, #1e1e3a, #2a2a50);
}
.newsletter-form input[type="email"] {
background: var(--color-surface);
color: var(--color-ink);
border-color: var(--color-border);
}
}