Skip to content

Commit cb29ed8

Browse files
authored
Merge pull request #145 from DefGuard/blog_revamp
Enhance blog component and pages: refactor MoreStories component to i…
2 parents 850a5ce + 9a8b31f commit cb29ed8

15 files changed

+577
-190
lines changed

src/components/MoreStories.astro

Lines changed: 120 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ interface Props {
88
99
const { currentSlug, posts } = Astro.props;
1010
11+
// Default fallback image
12+
const defaultImage = "/images/png/defguard.png";
13+
14+
// Get image for a post
15+
const getPostImage = (post: CollectionEntry<"blog">) => {
16+
return post.data.image || defaultImage;
17+
};
18+
1119
// Format date function
1220
const formatDate = (date: Date) => {
1321
return new Date(date).toLocaleDateString("en-US", {
@@ -17,6 +25,12 @@ const formatDate = (date: Date) => {
1725
});
1826
};
1927
28+
// Truncate description
29+
const truncateDescription = (text: string, maxLength: number = 100) => {
30+
if (text.length <= maxLength) return text;
31+
return text.slice(0, maxLength).trim() + "...";
32+
};
33+
2034
// Filter out current post and get 3 random posts
2135
const otherPosts = posts.filter((post) => post.slug !== currentSlug);
2236
const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
@@ -29,23 +43,27 @@ const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
2943
{
3044
selectedPosts.map((post) => (
3145
<article class="post-card">
32-
<h3 class="post-title">
33-
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
34-
</h3>
35-
<div class="post-meta">
36-
<time datetime={post.data.publishDate.toISOString()}>
37-
{formatDate(post.data.publishDate)}
38-
</time>
39-
{post.data.author && <span class="post-author">by {post.data.author}</span>}
40-
</div>
41-
{post.data.companyName && (
42-
<p>
43-
<span class="case-study-label">Case Study</span>
44-
</p>
45-
)}
46-
<p class="post-description">{post.data.description}</p>
47-
<a href={`/blog/${post.slug}`} class="read-more">
48-
Read more →
46+
<a href={`/blog/${post.slug}`} class="post-card-link">
47+
<div class="post-image-wrapper">
48+
<img
49+
src={getPostImage(post)}
50+
alt={post.data.title}
51+
loading="lazy"
52+
class="post-image"
53+
/>
54+
{post.data.companyName && (
55+
<span class="card-badge-case-study">Case Study</span>
56+
)}
57+
</div>
58+
<div class="post-content">
59+
<h3 class="post-title">{post.data.title}</h3>
60+
<p class="post-description">{truncateDescription(post.data.description)}</p>
61+
<div class="post-meta">
62+
<time datetime={post.data.publishDate.toISOString()}>
63+
{formatDate(post.data.publishDate)}
64+
</time>
65+
</div>
66+
</div>
4967
</a>
5068
</article>
5169
))
@@ -67,109 +85,123 @@ const selectedPosts = otherPosts.sort(() => Math.random() - 0.5).slice(0, 3);
6785

6886
.section-title {
6987
margin: 0 0 2rem;
70-
font-size: calc(1rem * var(--font-scale-factor));
71-
font-weight: 400;
88+
font-size: calc(1.1rem * var(--font-scale-factor));
89+
font-weight: 500;
7290
color: var(--text-body-primary);
7391
text-align: left;
74-
padding-left: 20px;
7592
}
7693

7794
.posts-grid {
7895
display: grid;
79-
grid-template-columns: repeat(1, 1fr);
80-
gap: 25px;
96+
grid-template-columns: 1fr;
97+
gap: 24px;
8198

8299
@media (min-width: 640px) {
83100
grid-template-columns: repeat(2, 1fr);
84-
gap: 30px;
101+
gap: 28px;
85102
}
86103

87104
@media (min-width: 1024px) {
88105
grid-template-columns: repeat(3, 1fr);
89-
gap: 40px;
106+
gap: 32px;
90107
}
91108
}
92109

93110
.post-card {
94-
display: block;
95-
text-decoration: none;
96-
color: inherit;
97-
padding: 20px;
98-
background-color: #f9f9f9;
99-
border-width: 0 0 2px 0;
100-
border-style: solid;
101-
border-color: #f5f5f5;
102-
transition:
103-
transform 0.2s ease,
104-
box-shadow 0.2s ease,
105-
border-color 0.2s ease;
106-
transform: translateY(0);
107-
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03);
111+
background: white;
112+
border-radius: 10px;
113+
overflow: hidden;
114+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
115+
transition: transform 0.25s ease, box-shadow 0.25s ease;
108116

109117
&:hover {
110-
transform: translateY(-5px);
111-
border-color: var(--primary-button-bg, #0c8ce0);
112-
}
118+
transform: translateY(-6px);
119+
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.1);
113120

114-
.post-title {
115-
margin: 0 0 15px 0;
116-
font-size: calc(1.5rem * var(--font-scale-factor));
117-
font-weight: 400;
118-
119-
a {
120-
color: var(--text-body-primary);
121-
text-decoration: none;
122-
&:hover {
123-
color: var(--primary-button-bg, #0c8ce0);
124-
}
121+
.post-image {
122+
transform: scale(1.05);
123+
}
124+
125+
.post-title {
126+
color: var(--primary-button-bg, #0c8ce0);
125127
}
126128
}
127129

128-
.post-meta {
129-
display: flex;
130-
flex-wrap: wrap;
131-
gap: 0.5rem;
132-
color: var(--text-body-secondary);
133-
margin-bottom: 8px;
134-
font-size: 14px;
135-
font-weight: 300;
130+
.post-card-link {
131+
display: block;
132+
text-decoration: none;
133+
color: inherit;
134+
}
136135

137-
.post-author {
138-
&::before {
139-
content: "•";
140-
margin-right: 0.5rem;
141-
}
142-
}
136+
.post-image-wrapper {
137+
position: relative;
138+
overflow: hidden;
139+
background: #f8f8f8;
143140
}
144141

145-
.post-description {
146-
margin: 1rem 0;
147-
line-height: 1.6;
148-
font-weight: 300;
149-
color: var(--text-body-primary);
150-
font-size: calc(1rem * var(--font-scale-factor));
142+
.post-image {
143+
width: 100%;
144+
height: auto;
145+
display: block;
146+
transition: transform 0.4s ease;
151147
}
152148

153-
.case-study-label {
154-
display: inline-block;
155-
color: var(--surface-main-primary);
149+
.card-badge-case-study {
150+
position: absolute;
151+
top: 12px;
152+
left: 12px;
153+
padding: 4px 10px;
154+
background: rgba(255, 255, 255, 0.95);
155+
color: #166534;
156156
font-size: 10px;
157-
font-weight: 400;
158-
padding: 5px 10px;
159-
margin-bottom: 0.5rem;
160-
border-radius: 50px;
161-
background-color: #f5f5f5;
162-
border: 1px solid var(--surface-main-primary);
157+
font-weight: 600;
158+
text-transform: uppercase;
159+
letter-spacing: 0.5px;
160+
border-radius: 4px;
161+
backdrop-filter: blur(4px);
162+
}
163+
164+
.post-content {
165+
padding: 1.25rem;
166+
}
167+
168+
.post-title {
169+
margin: 0 0 0.75rem;
170+
font-size: 1.1rem;
171+
font-weight: 500;
172+
line-height: 1.4;
173+
color: var(--text-body-primary);
174+
transition: color 0.2s ease;
175+
176+
// Clamp to 2 lines
177+
display: -webkit-box;
178+
-webkit-line-clamp: 2;
179+
-webkit-box-orient: vertical;
180+
overflow: hidden;
163181
}
164182

165-
.read-more {
166-
display: inline-block;
167-
color: var(--primary-text-color);
168-
font-size: 14px;
183+
.post-description {
184+
margin: 0 0 1rem;
185+
font-size: 0.9rem;
186+
line-height: 1.5;
187+
color: var(--text-body-secondary, #666);
169188
font-weight: 300;
170-
text-decoration: none;
171-
&:hover {
172-
text-decoration: underline;
189+
190+
// Clamp to 2 lines for more stories
191+
display: -webkit-box;
192+
-webkit-line-clamp: 2;
193+
-webkit-box-orient: vertical;
194+
overflow: hidden;
195+
}
196+
197+
.post-meta {
198+
display: flex;
199+
align-items: center;
200+
font-size: 12px;
201+
color: var(--text-body-secondary, #888);
202+
203+
time {
204+
font-weight: 400;
173205
}
174206
}
175207
}

src/content/blog/defguard-1.5-release-notes.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
---
22
title: Release 1.5 with Mobile apps, External SSO MFA, MFA with Biometry
33
publishDate: 2025-09-15
4-
description: This is the biggest, most feature packed release we have ever done! Weve introduced 11 major features and nearly 100 bugfixes.
4+
description: This is the biggest, most feature packed release we have ever done! We've introduced 11 major features and nearly 100 bugfixes.
55
draft: false
6+
image: "/images/blog/defguard-1.5-release-notes/15_release_1.png"
7+
tags: ["release", "mobile app", "mfa", "biometry", "sso", "wireguard", "ios", "android"]
68
---
79

810
import YouTubeVideo from "../../components/video/YouTubeVideo.astro";

src/content/blog/defguard-pre-seed.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Defguard has established strategic partnerships with top open-sour
55
author: "Michał Gryczka"
66

77
image: "/images/blog/defguard_founders_and_Hard2beat_partners.png"
8+
tags: ["news", "funding", "pre-seed", "startup", "venture capital", "partnership"]
89
---
910

1011
import YouTubeVideo from "../../components/video/YouTubeVideo.astro";

src/content/blog/defguard-release.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Defguard offers a unique combination of security-related functiona
55
author: "Robert Olejnik"
66

77
image: "/images/blog/defguard-main-screen.png"
8+
tags: ["release", "launch", "wireguard", "zero-trust", "mfa", "open source", "identity management"]
89
---
910

1011
### TL;DR

src/content/blog/fortitoken-alternative-vpn-mfa.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ description: "Stop paying the 'security tax.' Legacy VPNs like Fortinet treat MF
66
author: "Robert (Co-Founder, Defguard)"
77
image: "/images/blog/mfa-isnt-an-addon/mfa-hero.png"
88
draft: true
9+
tags: ["fortitoken", "mfa", "fortinet alternative", "security", "nis2", "vpn pricing"]
910
---
1011

1112
![Security shouldn't cost extra — MFA isn't an add-on](/images/blog/mfa-isnt-an-addon/mfa-hero.png)

src/content/blog/mfa-wireguard-nis2-compliance.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ publishDate: 2025-10-07
44
description: "The NIS2 Directive mandates MFA for VPNs. Learn how to implement true, connection-level Multi-Factor Authentication for VPNs using the WireGuard® protocol with Defguard to ensure compliance and top-tier security."
55
author: "Piotr Borkowicz"
66
image: "/images/blog/Defguard-nis2-mfa/wireguard-nis2-hero.png"
7+
tags: ["mfa", "wireguard", "nis2", "compliance", "2fa", "security", "enterprise"]
78
---
89

910
import MfaDiagram from '../../components/MfaDiagram.astro';

src/content/blog/prusa-vpn-scaling-with-defguard.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ companySegment: "Desktop and industrial 3D printing"
1010
companyWebsite: "https://www.prusa3d.com"
1111

1212
image: "/images/blog/prusa.png"
13+
tags: ["prusa", "enterprise vpn", "self-hosted", "wireguard", "mfa", "identity management"]
1314
---
1415

1516
![How Prusa Secured Global VPN Access with Defguard](/images/blog/prusa.png)

src/content/blog/self-hosted-vpn-private-cloud-acquinox-defguard.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ companySegment: "Private Equity"
1010
companyWebsite: "https://acquinox.capital"
1111

1212
image: "/images/blog/acquinox.png"
13+
tags: ["private cloud", "self-hosted", "data sovereignty", "sso", "finance", "gdpr"]
1314
---
1415

1516
![Private Equity firm builds secure private cloud with Defguard](/images/blog/acquinox.png)

src/content/blog/ssl-vpn-performance-protocol-problem.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: "Tired of users complaining your Fortinet VPN is slow? You're not a
55
author: "Piotr Borkowicz"
66
publishDate: 2025-11-12
77
image: "/images/blog/SSLVPN/SSL-VPN.png"
8+
tags: ["ssl vpn", "fortinet", "vpn performance", "wireguard", "migration", "enterprise vpn"]
89
---
910

1011
![Understanding SSL VPN Limitations: Transport, Mobility and Modern Alternatives](/images/blog/SSLVPN/SSL-VPN.png)

src/content/blog/why-open-source.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
title: "Why We Made Defguard Open Source"
33
publishDate: 2025-05-23
4-
description: "Discover how new Swiss laws are reshaping digital sovereignty — and why Defguards open source model is leading the way in secure, transparent infrastructure."
4+
description: "Discover how new Swiss laws are reshaping digital sovereignty — and why Defguard's open source model is leading the way in secure, transparent infrastructure."
55
author: "Michał Gryczka"
66

77
image: "/images/blog/swiss-dg.png"
8+
tags: ["open source", "digital sovereignty", "transparency", "swiss law", "embag", "security"]
89
---
910

1011
![](/images/blog/swiss-dg.png)

0 commit comments

Comments
 (0)