Skip to content

Commit 918a82b

Browse files
committed
feat(website): mobile menu UI polish and badge distortion fixes
1 parent 72e91cc commit 918a82b

5 files changed

Lines changed: 70 additions & 82 deletions

File tree

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ All notable changes to the EDDI website will be documented in this file.
44

55
## [Unreleased]
66
### 🐛 Bug Fixes
7+
- `fix(website)`: **Docker Pulls Badge Distortion** — Fixed stretched shields.io and GitHub Action badges on the homepage "Trusted & Certified" section by applying `w-auto` utility classes. This prevents aspect-ratio distortion while preserving the explicit HTML `width`/`height` attributes required to avoid Lighthouse CLS penalties.
78
- `fix(website)`: **Mobile CTA Stack Layout** — Re-implemented the mobile CTA button layout (Get Started / View on GitHub) to use a centered vertical flex column (`max-width: 20rem`) with 100% width buttons. This resolves cramped horizontal rendering while preventing oversized, edge-to-edge block stretching.
89
- `fix(website)`: **Hero Image Container Spacing** — Eliminated excessive trailing whitespace below hero images inside `.premium-image-wrapper` elements. Applied `display: flex` to the wrapper to remove block baseline gaps and enforced an explicit `aspect-ratio: 1 / 1` on the image itself, ensuring perfectly snug, high-fidelity responsive scaling without letterboxing.
910
- `fix(website)`: **Trust Badge Aspect Ratio** — Fixed stretched and squeezed social proof badges on the Track Record page by adding `width: auto` to prevent aspect ratio distortion when the height is CSS-constrained to `1.5rem`.
@@ -18,6 +19,7 @@ All notable changes to the EDDI website will be documented in this file.
1819
- `fix(website)`: **French Locale Parse Error** — Fixed curly right single quote (`'`) in `fr.ts` `timelineTitle` that broke the JavaScript string literal, causing build failures.
1920

2021
### 🎨 UI Enhancements
22+
- `feat(website)`: **Mobile Menu UI Polish** — Added emojis to all mobile navigation links to provide visual anchors and perfectly match the desktop dropdown menus. Updated category header typography to use the primary amber accent color (`var(--color-accent)`) and increased spacing for clear visual hierarchy on the dark navigation overlay.
2123
- `feat(website)`: **Getting Started Hero Image** — Added a 3D isometric hero image to the Getting Started page, matching the dark-charcoal-and-gold visual style used across all other feature and enterprise pages. Updated hero section from centered text-only layout to side-by-side text + image layout (matching FeaturePage layout).
2224

2325
### 🔐 Security Documentation

src/components/Header.astro

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -206,33 +206,33 @@ const t = await getTranslations(lang);
206206
<div class="eddi-mobile-inner">
207207
<div class="eddi-mobile-section">
208208
<h3>{t.nav.features}</h3>
209-
<a href={localePath(lang, '/features/overview/')}>{t.nav.allFeatures}</a>
210-
<a href={localePath(lang, '/features/manager/')}>{t.nav.eddiManager}</a>
211-
<a href={localePath(lang, '/features/mcp-server/')}>{t.nav.mcpServerMobile}</a>
212-
<a href={localePath(lang, '/features/config-as-code/')}>{t.nav.configAsCode}</a>
213-
<a href={localePath(lang, '/features/security/')}>{t.nav.securityFirst}</a>
214-
<a href={localePath(lang, '/features/performance/')}>{t.nav.performance}</a>
215-
<a href={localePath(lang, '/features/multi-agent/')}>{t.nav.multiAgent}</a>
216-
<a href={localePath(lang, '/features/observability/')}>{t.nav.observability}</a>
217-
<a href={localePath(lang, '/features/code-quality/')}>{t.nav.codeQuality}</a>
218-
<a href={localePath(lang, '/features/ai-ready/')}>{t.nav.aiReady}</a>
219-
<a href={localePath(lang, '/features/memory/')}>{t.nav.memory}</a>
220-
<a href={localePath(lang, '/features/rag/')}>{t.nav.rag}</a>
221-
<a href={localePath(lang, '/features/model-cascading/')}>{t.nav.modelCascading}</a>
222-
<a href={localePath(lang, '/features/scheduling/')}>{t.nav.scheduling}</a>
209+
<a href={localePath(lang, '/features/overview/')}><span class="eddi-mobile-icon">✨</span> {t.nav.allFeatures}</a>
210+
<a href={localePath(lang, '/features/manager/')}><span class="eddi-mobile-icon">🖥️</span> {t.nav.eddiManager}</a>
211+
<a href={localePath(lang, '/features/mcp-server/')}><span class="eddi-mobile-icon">🔌</span> {t.nav.mcpServerMobile}</a>
212+
<a href={localePath(lang, '/features/config-as-code/')}><span class="eddi-mobile-icon">⚙️</span> {t.nav.configAsCode}</a>
213+
<a href={localePath(lang, '/features/security/')}><span class="eddi-mobile-icon">🔐</span> {t.nav.securityFirst}</a>
214+
<a href={localePath(lang, '/features/performance/')}><span class="eddi-mobile-icon">🚀</span> {t.nav.performance}</a>
215+
<a href={localePath(lang, '/features/multi-agent/')}><span class="eddi-mobile-icon">🤖</span> {t.nav.multiAgent}</a>
216+
<a href={localePath(lang, '/features/observability/')}><span class="eddi-mobile-icon">📊</span> {t.nav.observability}</a>
217+
<a href={localePath(lang, '/features/code-quality/')}><span class="eddi-mobile-icon">🧪</span> {t.nav.codeQuality}</a>
218+
<a href={localePath(lang, '/features/ai-ready/')}><span class="eddi-mobile-icon">🧩</span> {t.nav.aiReady}</a>
219+
<a href={localePath(lang, '/features/memory/')}><span class="eddi-mobile-icon">🧠</span> {t.nav.memory}</a>
220+
<a href={localePath(lang, '/features/rag/')}><span class="eddi-mobile-icon">📚</span> {t.nav.rag}</a>
221+
<a href={localePath(lang, '/features/model-cascading/')}><span class="eddi-mobile-icon">📈</span> {t.nav.modelCascading}</a>
222+
<a href={localePath(lang, '/features/scheduling/')}><span class="eddi-mobile-icon">⏰</span> {t.nav.scheduling}</a>
223223
</div>
224224
<div class="eddi-mobile-section">
225225
<h3>{t.nav.solutions}</h3>
226-
<a href={localePath(lang, '/enterprise/why-eddi/')}>{t.nav.whyEddi}</a>
227-
<a href={localePath(lang, '/enterprise/vs-alternatives/')}>{t.nav.vsAlternatives}</a>
228-
<a href={localePath(lang, '/enterprise/compliance/')}>{t.nav.euAiAct}</a>
229-
<a href={localePath(lang, '/enterprise/trust/')}>{t.nav.trackRecord}</a>
230-
<a href={localePath(lang, '/use-cases/')}>{t.nav.useCases}</a>
226+
<a href={localePath(lang, '/enterprise/why-eddi/')}><span class="eddi-mobile-icon">💡</span> {t.nav.whyEddi}</a>
227+
<a href={localePath(lang, '/enterprise/vs-alternatives/')}><span class="eddi-mobile-icon">⚖️</span> {t.nav.vsAlternatives}</a>
228+
<a href={localePath(lang, '/enterprise/compliance/')}><span class="eddi-mobile-icon">🏛️</span> {t.nav.euAiAct}</a>
229+
<a href={localePath(lang, '/enterprise/trust/')}><span class="eddi-mobile-icon">📜</span> {t.nav.trackRecord}</a>
230+
<a href={localePath(lang, '/use-cases/')}><span class="eddi-mobile-icon">📋</span> {t.nav.useCases}</a>
231231
</div>
232232
<div class="eddi-mobile-section">
233233
<h3>{t.nav.resources}</h3>
234-
<a href="https://docs.labs.ai" target="_blank" rel="noopener">{t.nav.documentation}</a>
235-
<a href="https://github.com/labsai/EDDI" target="_blank" rel="noopener">{t.nav.github}</a>
234+
<a href="https://docs.labs.ai" target="_blank" rel="noopener"><span class="eddi-mobile-icon">📖</span> {t.nav.documentation}</a>
235+
<a href="https://github.com/labsai/EDDI" target="_blank" rel="noopener"><span class="eddi-mobile-icon">🐙</span> {t.nav.github}</a>
236236
</div>
237237
<div class="eddi-mobile-cta">
238238
<a href={localePath(lang, '/getting-started/')} class="eddi-cta">{t.nav.getStarted}</a>
@@ -582,29 +582,37 @@ const t = await getTranslations(lang);
582582
}
583583

584584
.eddi-mobile-section h3 {
585-
font-size: 0.625rem;
586-
font-weight: 700;
585+
font-size: 0.6875rem;
586+
font-weight: 800;
587587
text-transform: uppercase;
588588
letter-spacing: 0.08em;
589-
color: var(--color-text-subtle);
590-
margin: 0; margin-block-end: 0.375rem; margin-inline-start: 0.625rem;
589+
color: var(--color-accent);
590+
margin: 0; margin-block-end: 0.5rem; margin-inline-start: 0.625rem;
591591
}
592592

593593
.eddi-mobile-section a {
594594
display: block;
595595
padding: 0.625rem 0.75rem;
596596
color: var(--color-text-muted);
597597
text-decoration: none;
598-
font-size: 0.875rem;
598+
font-size: 0.9375rem;
599+
font-weight: 500;
599600
border-radius: 0.375rem;
600-
transition: background 0.15s;
601+
transition: background 0.15s, color 0.15s;
601602
min-height: 2.75rem;
602603
display: flex;
603604
align-items: center;
605+
gap: 0.75rem;
604606
}
605607

606608
.eddi-mobile-section a:hover {
607609
background: var(--color-surface);
610+
color: var(--color-text);
611+
}
612+
613+
.eddi-mobile-icon {
614+
font-size: 1.125rem;
615+
flex-shrink: 0;
608616
}
609617

610618
.eddi-mobile-cta {

src/components/pages/HomeContent.astro

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ const { lang, t } = Astro.props;
3030
</h1>
3131
<p class="hero-tagline" set:html={t.home.heroTagline} />
3232
<div class="hero-actions">
33-
<a href={localePath(lang, '/getting-started/')} class="hero-btn-primary">{t.common.getStartedCta}</a>
34-
<a href="https://github.com/labsai/EDDI" class="hero-btn-minimal" target="_blank" rel="noopener">{t.common.viewOnGithub}</a>
33+
<a href={localePath(lang, '/getting-started/')} class="btn-cta-primary">{t.common.getStartedCta}</a>
34+
<a href="https://github.com/labsai/EDDI" class="btn-cta-outline" target="_blank" rel="noopener">{t.common.viewOnGithub}</a>
3535
</div>
3636
</div>
37-
<div class="hero-visual premium-image-wrapper">
37+
<div class="premium-image-wrapper">
3838
<Image src={heroImage} alt="EDDI AI Orchestrator" width={1024} height={1024} loading="eager" decoding="async" />
3939
</div>
4040
</div>
@@ -115,8 +115,8 @@ const { lang, t } = Astro.props;
115115
{ title: t.home.trustRedHat, desc: t.home.trustRedHatDesc, icon: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>' },
116116
{ title: t.home.trustApache, desc: t.home.trustApacheDesc, icon: '<path d="M9 12l2 2 4-4"/><circle cx="12" cy="12" r="10"/>' },
117117
{ title: t.home.trustTests, desc: t.home.trustTestsDesc, icon: '<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/>' },
118-
{ title: t.home.trustDocker, desc: t.home.trustDockerDesc, icon: '<rect x="2" y="7" width="20" height="14" rx="2"/><path d="M12 7V3"/><path d="M2 13h20"/><rect x="5" y="10" width="3" height="3"/><rect x="10" y="10" width="3" height="3"/><rect x="15" y="10" width="3" height="3"/><rect x="5" y="15" width="3" height="3"/><rect x="10" y="15" width="3" height="3"/>', href: 'https://hub.docker.com/r/labsai/eddi', badge: '<div class="mt-2"><img src="https://img.shields.io/docker/pulls/labsai/eddi?style=flat-square&color=f59e0b&labelColor=27272a" alt="Docker Pulls" class="h-5" width="150" height="20" loading="lazy" /></div>' },
119-
{ title: t.home.trustCI, desc: t.home.trustCIDesc, icon: '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>', href: 'https://github.com/labsai/EDDI/actions/workflows/ci.yml', badge: '<div class="mt-2 flex flex-wrap gap-2"><img src="https://github.com/labsai/EDDI/actions/workflows/ci.yml/badge.svg" alt="CI" class="h-5 inline-block" width="120" height="20" loading="lazy" /><img src="https://github.com/labsai/EDDI/actions/workflows/codeql.yml/badge.svg" alt="CodeQL" class="h-5 inline-block" width="120" height="20" loading="lazy" /></div>' },
118+
{ title: t.home.trustDocker, desc: t.home.trustDockerDesc, icon: '<rect x="2" y="7" width="20" height="14" rx="2"/><path d="M12 7V3"/><path d="M2 13h20"/><rect x="5" y="10" width="3" height="3"/><rect x="10" y="10" width="3" height="3"/><rect x="15" y="10" width="3" height="3"/><rect x="5" y="15" width="3" height="3"/><rect x="10" y="15" width="3" height="3"/>', href: 'https://hub.docker.com/r/labsai/eddi', badge: '<div class="mt-2"><img src="https://img.shields.io/docker/pulls/labsai/eddi?style=flat-square&color=f59e0b&labelColor=27272a" alt="Docker Pulls" class="h-5 w-auto" width="134" height="20" loading="lazy" /></div>' },
119+
{ title: t.home.trustCI, desc: t.home.trustCIDesc, icon: '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>', href: 'https://github.com/labsai/EDDI/actions/workflows/ci.yml', badge: '<div class="mt-2 flex flex-wrap gap-2"><img src="https://github.com/labsai/EDDI/actions/workflows/ci.yml/badge.svg" alt="CI" class="h-5 w-auto inline-block" width="98" height="20" loading="lazy" /><img src="https://github.com/labsai/EDDI/actions/workflows/codeql.yml/badge.svg" alt="CodeQL" class="h-5 w-auto inline-block" width="98" height="20" loading="lazy" /></div>' },
120120
].map((item) => {
121121
const inner = (
122122
<>
@@ -227,32 +227,17 @@ const { lang, t } = Astro.props;
227227
html[data-theme='dark'] .hero-tagline { color: rgba(255, 255, 255, 0.6); }
228228
html[data-theme='light'] .hero-tagline { color: rgba(0, 0, 0, 0.6); }
229229
.hero-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
230-
.hero-btn-primary { display: inline-flex; align-items: center; justify-content: center; padding: 0.75rem 1.75rem; font-size: 1rem; font-weight: 600; color: #111 !important; background: linear-gradient(135deg, var(--color-accent-400), var(--color-accent-600)); border-radius: 0.5rem; text-decoration: none; transition: all 0.3s ease; box-shadow: 0 0 20px color-mix(in srgb, var(--color-accent) 25%, transparent); }
231-
.hero-btn-primary:hover { transform: translateY(-2px); box-shadow: 0 0 30px color-mix(in srgb, var(--color-accent) 45%, transparent); }
232-
.hero-btn-minimal { display: inline-flex; align-items: center; justify-content: center; padding: 0.75rem 1.75rem; font-size: 1rem; font-weight: 500; border-radius: 0.5rem; text-decoration: none; transition: all 0.3s ease; }
233-
html[data-theme='dark'] .hero-btn-minimal { color: rgba(255, 255, 255, 0.8); border: 1px solid rgba(255, 255, 255, 0.15); }
234-
html[data-theme='light'] .hero-btn-minimal { color: #333; border: 1px solid rgba(0, 0, 0, 0.15); }
235-
.hero-btn-minimal:hover { transform: translateY(-2px); }
236-
.hero-visual { flex-shrink: 0; border-radius: 1.25rem; overflow: hidden; box-shadow: 0 25px 60px rgba(0, 0, 0, 0.4); }
237-
html[data-theme='light'] .hero-visual { background: #f0f1f3; border: 1px solid rgba(0, 0, 0, 0.08); box-shadow: 0 25px 60px rgba(0, 0, 0, 0.12); }
238-
.hero-visual img { display: block; width: 100%; height: auto; max-width: 28rem; object-fit: contain; }
239230
@media (max-width: 64rem) {
240231
.hero-inner { gap: 2.5rem; }
241-
.hero-visual img { max-width: 20rem; }
242232
}
243233
@media (max-width: 50rem) {
244234
.hero-inner { flex-direction: column; text-align: center; gap: 2.5rem; }
245235
.hero-tagline { max-width: none; }
246236
.hero-actions { justify-content: center; gap: 0.75rem; }
247-
.hero-btn-primary,
248-
.hero-btn-minimal { padding: 0.625rem 1.5rem; font-size: 0.9375rem; }
249-
.hero-visual { max-width: 20rem; }
250237
}
251238
@media (max-width: 30rem) {
252-
.hero-actions { justify-content: center; margin: 0 auto; gap: 0.75rem; flex-direction: column; align-items: stretch; width: 100%; max-width: 20rem; }
253-
.hero-btn-primary,
254-
.hero-btn-minimal { padding: 0.75rem 1.25rem; font-size: 0.9375rem; width: 100%; justify-content: center; text-align: center; }
255-
.hero-visual { max-width: 16rem; }
239+
.hero-inner { gap: 1.5rem; }
240+
.hero-actions { justify-content: center; margin: 0 auto; gap: 0.75rem; flex-direction: column; align-items: stretch; width: 100%; max-width: 15rem; }
256241
}
257242
/* Trusted & Certified — uniform 5-card grid */
258243
.trust-grid {

src/layouts/FeaturePage.astro

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const t = await getTranslations(lang);
3333
</div>
3434
</div>
3535
{heroImage && (
36-
<div class="fp-hero-image premium-image-wrapper">
36+
<div class="premium-image-wrapper">
3737
<Image src={heroImage} alt={title} width={1024} height={1024} loading="eager" decoding="async" />
3838
</div>
3939
)}
@@ -86,26 +86,6 @@ const t = await getTranslations(lang);
8686
flex-wrap: wrap;
8787
}
8888

89-
.fp-hero-image {
90-
flex-shrink: 0;
91-
border-radius: 1rem;
92-
overflow: hidden;
93-
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
94-
}
95-
96-
html[data-theme='light'] .fp-hero-image {
97-
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.1);
98-
border: 1px solid rgba(0, 0, 0, 0.08);
99-
}
100-
101-
.fp-hero-image img {
102-
display: block;
103-
width: 100%;
104-
height: auto;
105-
max-width: 28rem;
106-
object-fit: contain;
107-
}
108-
10989
.fp-content {
11090
max-width: 72rem;
11191
margin: 0 auto;
@@ -147,7 +127,6 @@ const t = await getTranslations(lang);
147127

148128
@media (max-width: 64rem) {
149129
.fp-hero-inner { gap: 2rem; }
150-
.fp-hero-image img { max-width: 20rem; }
151130
}
152131
@media (max-width: 50rem) {
153132
.fp-hero-inner {
@@ -159,17 +138,16 @@ const t = await getTranslations(lang);
159138
justify-content: center;
160139
gap: 0.75rem;
161140
}
162-
.fp-hero-image { max-width: 20rem; }
163141
}
164142
@media (max-width: 30rem) {
143+
.fp-hero-inner { gap: 1.5rem; }
165144
.fp-hero-actions {
166145
justify-content: center;
167146
margin: 0 auto;
168147
flex-direction: column;
169148
align-items: stretch;
170149
width: 100%;
171-
max-width: 20rem;
150+
max-width: 15rem;
172151
}
173-
.fp-hero-image { max-width: 16rem; }
174152
}
175153
</style>

src/styles/global.css

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,11 @@ html[data-theme='light'] .hero-gradient-bg {
176176
}
177177
}
178178

179-
/* Mobile: stack CTA buttons full-width within a constrained container */
179+
/* Mobile: stack CTA buttons without forcing full-width */
180180
@media (max-width: 30rem) {
181181
.btn-cta-primary,
182182
.btn-cta-outline {
183183
padding: 0.75rem 1.25rem;
184-
width: 100%;
185-
justify-content: center;
186-
text-align: center;
187184
}
188185
}
189186

@@ -366,16 +363,23 @@ code:not(pre code) {
366363
padding: 0.5rem;
367364
background: color-mix(in srgb, var(--color-surface) 60%, transparent);
368365
border: 1px solid var(--color-border);
369-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
366+
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.35);
370367
overflow: hidden;
371368
transition: transform 0.3s ease, box-shadow 0.3s ease;
372369
display: flex;
373370
align-items: center;
374371
justify-content: center;
372+
margin: 0 auto;
373+
flex-shrink: 0;
374+
width: 100%;
375+
max-width: 28rem;
376+
aspect-ratio: 1 / 1;
375377
}
376378

377379
html[data-theme='light'] .premium-image-wrapper {
378-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
380+
background: #f0f1f3;
381+
border: 1px solid rgba(0, 0, 0, 0.08);
382+
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.12);
379383
}
380384

381385
.premium-image-wrapper:hover {
@@ -392,9 +396,20 @@ html[data-theme='light'] .premium-image-wrapper:hover {
392396
border: 1px solid color-mix(in srgb, var(--color-border) 40%, transparent);
393397
display: block;
394398
width: 100%;
395-
height: auto;
399+
height: 100%;
396400
object-fit: contain;
397-
aspect-ratio: 1 / 1;
401+
}
402+
403+
@media (max-width: 64rem) {
404+
.premium-image-wrapper {
405+
max-width: 20rem;
406+
}
407+
}
408+
409+
@media (max-width: 30rem) {
410+
.premium-image-wrapper {
411+
max-width: 16rem;
412+
}
398413
}
399414

400415
/* ==========================================================================

0 commit comments

Comments
 (0)