fix(home): remove <a> wrapper around bento-tile (was breaking grid)

The home service section had each bento-tile wrapped in an
<a href="/services/..."> tag. This caused two problems:

1. The <a> became the grid item instead of the .bento-tile,
   so the .bento-tile's grid-column: span 3 was ignored.
   The <a> defaulted to display: block and stretched to
   100% width, so all 4 tiles in a row had the same wide
   width — but the grid was no longer dividing them equally.

2. Astro's scoped CSS only applies to elements with the
   matching data-astro-cid attribute. The <a> wrapper had
   its own scope, and the .bento-grid > a selector wasn't
   styled — so the grid layout didn't propagate correctly.

Fix: remove the <a> wrapper. Make the whole tile clickable
by adding an absolutely-positioned <a class="tile-link-overlay">
inside the tile (covers the entire tile, sits behind text via
z-index). The .bento-tile is now a direct child of .bento-grid
and grid-column: span 3 works as expected.

Result: 4 tiles width 3/12 each, exactly filling one row,
clickable from anywhere on the tile.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Kunthawat Greethong
2026-06-09 20:00:52 +07:00
parent 9e7d27c03c
commit bd1c979f1a
2 changed files with 37 additions and 9 deletions

View File

@@ -148,16 +148,16 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
const span = 3; 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;"> <BentoTile span={span} surface={surface} eyebrow={s.data.badge} title={s.data.title}>
<BentoTile span={span} surface={surface} eyebrow={s.data.badge} title={s.data.title}> <p class="mega-subtitle">{s.data.subtitle}</p>
<p class="mega-subtitle">{s.data.subtitle}</p> <div class="mega-objective">
<div class="mega-objective"> <span class="objective-label">เป้าหมาย:</span>
<span class="objective-label">เป้าหมาย:</span> <span class="objective-value">{s.data.objective}</span>
<span class="objective-value">{s.data.objective}</span> </div>
</div> <a href={`/services/${s.id}`} class="tile-link-overlay">
<span class="mega-cta">ดูรายละเอียด →</span> <span class="mega-cta">ดูรายละเอียด →</span>
</BentoTile> </a>
</a> </BentoTile>
); );
})} })}
</BentoGrid> </BentoGrid>

View File

@@ -843,6 +843,34 @@ p {
min-height: 380px; min-height: 380px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative;
overflow: hidden;
transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease;
}
/* Invisible overlay link — makes the whole tile clickable
without breaking the bento-grid layout (no <a> wrapping) */
.tile-link-overlay {
position: absolute;
inset: 0;
z-index: 1;
text-decoration: none;
color: inherit;
display: flex;
align-items: flex-end;
padding: 32px;
}
.tile-link-overlay .mega-cta {
margin-top: 0;
font-weight: 700;
}
.bento-tile > *:not(.tile-link-overlay) {
position: relative;
z-index: 2;
}
.bento-tile:hover {
transform: translateY(-4px);
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.08);
} }
/* Make tile-body grow to push CTA to bottom */ /* Make tile-body grow to push CTA to bottom */