content(home): X1+X2 hero text + 2-col hero with pain stack + 2x2 services

Per user spec, restructured home page:

1. Hero copy (X1 + X2):
   - badge: "เราจะช่วยคุณเพิ่มกำไร"
   - title: "เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"
   - subtitle unchanged
   - replaced old "เว็บขายไม่ได้ โฆษณาเปลือง..." headline

2. Hero 2-column layout (text | pain stack):
   - Left 50%: badge, title, accent line, subtitle, CTA
   - Right 50%: 4 pain cards in vertical stack with colored
     surfaces (yellow, purple-soft, mint, teal) — staggered
     fade-in animation, each card has eyebrow "คุณกำลังเจอปัญหา"
     + pain question
   - Pain cards on right: "ยิ่งขาย กำไรยิ่งลด?", "มีเว็บไซต์
     เหมือนไม่มี?", "พนักงานทำงานได้น้อยกว่าที่ต้องการ?",
     "เอา AI มาให้ใช้ แต่งานไม่ได้มากขึ้นตามที่คิด?"
   - Responsive: stacks vertically on mobile (<1024px)
   - Pain card surfaces match bento tile vocabulary

3. Services section: 4x1 → 2x2 layout:
   - Each tile now span 6 (6+6 per row, 2 rows)
   - 4 tiles total: AI Consult (yellow), Automation (purple-soft),
     Marketing (mint), Web (soft)

4. Section title (X2):
   - "เริ่มจากอันที่ปวดที่สุด ค่อยขยายไปอันอื่น"
     → "เลือกบริการที่ตรงกับปัญหาของคุณ"

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Kunthawat Greethong
2026-06-09 21:13:43 +07:00
parent c92d446ff7
commit f47949c4b3
2 changed files with 167 additions and 49 deletions

View File

@@ -15,12 +15,18 @@ interface Props {
} }
const { const {
badge = "AI AGENCY ในประเทศไทย", badge = 'เราจะช่วยคุณเพิ่มกำไร',
title = "เว็บไซต์ที่ขายได้ ไม่ใช่แค่สวย", title = 'เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด',
subtitle = "เราออกแบบเว็บไซต์ + AI Chatbot + Marketing Automation ให้ธุรกิจไทยิ่มยอดขายเฉลี่ย 24 เท่า ภายใน 6 เดือน ด้วยงบที่จับต้องได้ เริ่มต้น 15,000 บาท", subtitle = 'รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กริ่มจากดูสถิติของคุณก่อน ไม่ใช่เดาว่าควรทำอะไร',
showCTA = true, showCTA = true,
ctaText = "เริ่มปรึกษาฟรี", ctaText = 'เริ่มปรึกษาฟรี',
ctaLink = "/contact", ctaLink = '/contact',
pains = [
{ surface: 'yellow', text: 'ยิ่งขาย กำไรยิ่งลด?' },
{ surface: 'purple-soft', text: 'มีเว็บไซต์ เหมือนไม่มี?' },
{ surface: 'mint', text: 'พนักงานทำงานได้น้อยกว่าที่ต้องการ?' },
{ surface: 'teal', text: 'เอา AI มาให้ใช้ แต่งานไม่ได้มากขึ้นตามที่คิด?' },
],
} = Astro.props; } = Astro.props;
// Split title into words for kinetic animation // Split title into words for kinetic animation
@@ -46,50 +52,66 @@ const titleWords = title.split(' ');
</div> </div>
<div class="container hero-container"> <div class="container hero-container">
<!-- Badge (data-animate for kineticHeadline words too) --> <!-- 2-COLUMN LAYOUT: text (left) + pain stack (right) -->
<div class="hero-badge" data-animate="fade-in"> <div class="hero-grid">
<span class="badge-dot"></span> <!-- LEFT: text content -->
{badge} <div class="hero-text">
</div> <!-- Badge -->
<div class="hero-badge" data-animate="fade-in">
<span class="badge-dot"></span>
{badge}
</div>
<!-- Main Title - Kinetic Typography (animated by lib/animations.ts kineticHeadline) --> <!-- Main Title - Kinetic Typography -->
<h1 class="hero-title kinetic-title"> <h1 class="hero-title kinetic-title">
{titleWords.map((word, index) => ( {titleWords.map((word, index) => (
<span class="word-wrapper"> <span class="word-wrapper">
<span <span
class="word" class="word"
style={`--delay: ${0.4 + index * 0.12}s`} style={`--delay: ${0.4 + index * 0.12}s`}
> >
{word} {word}
</span> </span>
</span> </span>
))} ))}
</h1> </h1>
<!-- Accent Line --> <!-- Accent Line -->
<div class="hero-accent-line"> <div class="hero-accent-line">
<div class="accent-fill"></div> <div class="accent-fill"></div>
</div> </div>
<!-- Subtitle --> <!-- Subtitle -->
<p class="hero-subtitle" data-animate="fade-in-up"> <p class="hero-subtitle" data-animate="fade-in-up">
<Fragment set:html={subtitle} /> <Fragment set:html={subtitle} />
</p> </p>
<!-- CTA Buttons --> <!-- CTA Buttons -->
{showCTA && ( {showCTA && (
<div class="hero-actions" data-animate="fade-in-up"> <div class="hero-actions" data-animate="fade-in-up">
<a href={ctaLink} class="btn btn-primary btn-magnetic"> <a href={ctaLink} class="btn btn-primary btn-magnetic">
<span class="btn-text">{ctaText}</span> <span class="btn-text">{ctaText}</span>
<svg class="btn-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"> <svg class="btn-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
<path d="M5 12h14M12 5l7 7-7 7"/> <path d="M5 12h14M12 5l7 7-7 7"/>
</svg> </svg>
</a> </a>
<slot name="hero-cta-secondary" /> <slot name="hero-cta-secondary" />
</div>
)}
<slot name="hero-trust" />
</div> </div>
)}
<slot name="hero-trust" /> <!-- RIGHT: pain card stack -->
<div class="hero-pain-stack" data-animate="fade-in-up">
{pains.map((p, i) => (
<div class={`pain-card pain-${p.surface}`} style={`--pain-delay: ${0.6 + i * 0.15}s`}>
<div class="pain-eyebrow">คุณกำลังเจอปัญหา</div>
<div class="pain-text">{p.text}</div>
</div>
))}
</div>
</div>
</div> </div>
<!-- Giant Background Typography --> <!-- Giant Background Typography -->
@@ -274,7 +296,103 @@ const titleWords = title.split(' ');
position: relative; position: relative;
z-index: 1; z-index: 1;
padding: 140px var(--gutter) 100px; padding: 140px var(--gutter) 100px;
max-width: 1200px; max-width: 1600px;
}
/* ============================================
HERO GRID — 2 COLUMNS (text + pain stack)
============================================ */
.hero-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 60px;
align-items: center;
}
.hero-text {
min-width: 0;
}
.hero-pain-stack {
display: flex;
flex-direction: column;
gap: 20px;
min-width: 0;
}
.pain-card {
padding: 28px 32px;
border-radius: var(--radius-xl);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08);
border: 1px solid transparent;
opacity: 0;
transform: translateY(20px);
animation: painReveal 0.7s var(--ease-out-expo) var(--pain-delay, 0s) forwards;
transition: transform 0.4s var(--ease-out-expo);
}
.pain-card:hover {
transform: translateY(-4px);
}
@keyframes painReveal {
to {
opacity: 1;
transform: translateY(0);
}
}
.pain-yellow {
background: var(--color-primary);
color: var(--color-black);
}
.pain-purple-soft {
background: var(--color-purple-soft);
color: var(--color-black);
}
.pain-mint {
background: var(--color-mint-soft);
color: var(--color-black);
}
.pain-teal {
background: var(--color-teal);
color: var(--color-white);
}
.pain-teal .pain-eyebrow { color: var(--color-primary); }
.pain-eyebrow {
font-family: var(--font-display);
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 2px;
opacity: 0.7;
margin-bottom: 8px;
}
.pain-text {
font-family: var(--font-display);
font-size: 22px;
font-weight: 800;
line-height: 1.3;
}
@media (max-width: 1024px) {
.hero-grid {
grid-template-columns: 1fr;
gap: 40px;
}
.hero-text {
order: 1;
}
.hero-pain-stack {
order: 2;
}
}
@media (max-width: 640px) {
.pain-text { font-size: 18px; }
.pain-card { padding: 20px 24px; }
} }
/* ============================================ /* ============================================

View File

@@ -76,8 +76,8 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
<Navigation /> <Navigation />
<Hero <Hero
badge="ที่ปรึกษาที่วางกลยุทธ์จากข้อมูล ไม่ใช่จากประสบการณ์ล้วน ๆ" badge="เราจะช่วยคุณเพิ่มกำไร"
title="เว็บขายไม่ได้ โฆษณาเปลือง งานซ้ำเติมคน — เราแก้ให้ตรงจุด" title="เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"
subtitle="รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กร เริ่มจากดูสถิติของคุณก่อน ไม่ใช่เดาว่าควรทำอะไร" subtitle="รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กร เริ่มจากดูสถิติของคุณก่อน ไม่ใช่เดาว่าควรทำอะไร"
> >
<a slot="hero-cta-secondary" href="/portfolio" class="btn btn-outline-dark"> <a slot="hero-cta-secondary" href="/portfolio" class="btn btn-outline-dark">
@@ -137,7 +137,7 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
<div class="section-header reveal"> <div class="section-header reveal">
<span class="section-badge">บริการของเรา</span> <span class="section-badge">บริการของเรา</span>
<h2 class="section-title"> <h2 class="section-title">
ริ่มจากอันที่ปวดที่สุด <span class="highlight">ค่อยขยายไปอันอื่น</span> ลือกบริการที่<span class="highlight">ตรงกับปัญหาของคุณ</span>
</h2> </h2>
<p class="section-desc">ไม่จำเป็นต้องทำทุกอย่างพร้อมกัน</p> <p class="section-desc">ไม่จำเป็นต้องทำทุกอย่างพร้อมกัน</p>
</div> </div>
@@ -167,8 +167,8 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
objective: 'เพิ่มยอดขาย และความน่าเชื่อถือให้ธุรกิจ', objective: 'เพิ่มยอดขาย และความน่าเชื่อถือให้ธุรกิจ',
}, },
]; ];
// Equal 4x3 tiles (full width, 1 row) // 2x2 layout — each tile span 6 (6+6 per row, 2 rows)
const span = 3; const span = 6;
const surface = (['yellow', 'purple-soft', 'mint', 'soft'] as const)[i]; const surface = (['yellow', 'purple-soft', 'mint', 'soft'] as const)[i];
const copy = tileCopy[i]; const copy = tileCopy[i];
return ( return (