fix(home): equal-height service tiles + dedupe services

Service section on home page had two issues:
1. Tiles were different heights (longer content = taller tile)
   because .bento-tile had no min-height
2. Two service tiles showed the same title (AI Consult + Automation
   Consult) because src/content/services/ has 4 old + 4 -new mdx
   files; .slice(0, 4) grabbed the first 4 alphabetically which
   contained duplicate base slugs

Fixes:
- Add min-height: 380px + flex column to BentoTile so all tiles
  in a row are visually equal regardless of content length
- Add dedupedServices helper in index.astro that groups services
  by base slug and prefers the -new version when both exist
- Use dedupedServices.slice(0, 4) instead of services.slice(0, 4)

Result: 4 unique services (ai-consult-new, automation-new,
marketing-new, webdev-new) at equal height, filling the row.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Kunthawat Greethong
2026-06-09 13:40:42 +07:00
parent b5be45bcd6
commit 43f609a794
2 changed files with 25 additions and 3 deletions

View File

@@ -67,6 +67,9 @@ const revealClass = reveal ? 'reveal' : '';
overflow: hidden; overflow: hidden;
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease; transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease;
transform-style: preserve-3d; transform-style: preserve-3d;
min-height: 380px;
display: flex;
flex-direction: column;
} }
.bento-tile:hover { .bento-tile:hover {
transform: translateY(-4px); transform: translateY(-4px);

View File

@@ -49,6 +49,25 @@ const problemCards = [
const problemSurfaces = ['yellow', 'purple-soft', 'mint', 'soft'] as const; const problemSurfaces = ['yellow', 'purple-soft', 'mint', 'soft'] as const;
const services = await getCollection('services'); const services = await getCollection('services');
// De-duplicate services: keep only the `-new` version when both old and new exist
// for the same base slug. Falls back to the old one if no `-new` exists.
// Group by base slug (strip trailing `-new` if present).
const dedupedServices = (() => {
const byBase = new Map<string, typeof services[number]>();
for (const s of services) {
const base = s.id.endsWith('-new') ? s.id.slice(0, -4) : s.id;
const existing = byBase.get(base);
if (!existing) {
byBase.set(base, s);
} else if (s.id.endsWith('-new') && !existing.id.endsWith('-new')) {
// Prefer the -new version
byBase.set(base, s);
}
}
return Array.from(byBase.values());
})();
const portfolio = await getCollection('portfolio'); const portfolio = await getCollection('portfolio');
const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4); const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
--- ---
@@ -124,9 +143,9 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
</div> </div>
<BentoGrid> <BentoGrid>
{services.slice(0, 4).map((s, i) => { {dedupedServices.slice(0, 4).map((s, i) => {
// Asymmetric layout: 8 + 4, 4 + 8 — alternating // Equal 4x3 tiles (full width, 1 row)
const span = i % 2 === 0 ? 8 : 4; const span = 3;
const surface = (['yellow', 'purple-soft', 'mint', 'soft'] as const)[i]; const surface = (['yellow', 'purple-soft', 'mint', 'soft'] as const)[i];
return ( return (
<a href={`/services/${s.id}`} style="display: block; text-decoration: none; color: inherit;"> <a href={`/services/${s.id}`} style="display: block; text-decoration: none; color: inherit;">