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:
@@ -15,12 +15,18 @@ interface Props {
|
||||
}
|
||||
|
||||
const {
|
||||
badge = "AI AGENCY ในประเทศไทย",
|
||||
title = "เว็บไซต์ที่ขายได้ ไม่ใช่แค่สวย",
|
||||
subtitle = "เราออกแบบเว็บไซต์ + AI Chatbot + Marketing Automation ให้ธุรกิจไทย เพิ่มยอดขายเฉลี่ย 2–4 เท่า ภายใน 6 เดือน ด้วยงบที่จับต้องได้ เริ่มต้น 15,000 บาท",
|
||||
badge = 'เราจะช่วยคุณเพิ่มกำไร',
|
||||
title = 'เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด',
|
||||
subtitle = 'รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กร เริ่มจากดูสถิติของคุณก่อน ไม่ใช่เดาว่าควรทำอะไร',
|
||||
showCTA = true,
|
||||
ctaText = "เริ่มปรึกษาฟรี",
|
||||
ctaLink = "/contact",
|
||||
ctaText = 'เริ่มปรึกษาฟรี',
|
||||
ctaLink = '/contact',
|
||||
pains = [
|
||||
{ surface: 'yellow', text: 'ยิ่งขาย กำไรยิ่งลด?' },
|
||||
{ surface: 'purple-soft', text: 'มีเว็บไซต์ เหมือนไม่มี?' },
|
||||
{ surface: 'mint', text: 'พนักงานทำงานได้น้อยกว่าที่ต้องการ?' },
|
||||
{ surface: 'teal', text: 'เอา AI มาให้ใช้ แต่งานไม่ได้มากขึ้นตามที่คิด?' },
|
||||
],
|
||||
} = Astro.props;
|
||||
|
||||
// Split title into words for kinetic animation
|
||||
@@ -46,50 +52,66 @@ const titleWords = title.split(' ');
|
||||
</div>
|
||||
|
||||
<div class="container hero-container">
|
||||
<!-- Badge (data-animate for kineticHeadline words too) -->
|
||||
<div class="hero-badge" data-animate="fade-in">
|
||||
<span class="badge-dot"></span>
|
||||
{badge}
|
||||
</div>
|
||||
<!-- 2-COLUMN LAYOUT: text (left) + pain stack (right) -->
|
||||
<div class="hero-grid">
|
||||
<!-- LEFT: text content -->
|
||||
<div class="hero-text">
|
||||
<!-- 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) -->
|
||||
<h1 class="hero-title kinetic-title">
|
||||
{titleWords.map((word, index) => (
|
||||
<span class="word-wrapper">
|
||||
<span
|
||||
class="word"
|
||||
style={`--delay: ${0.4 + index * 0.12}s`}
|
||||
>
|
||||
{word}
|
||||
</span>
|
||||
</span>
|
||||
))}
|
||||
</h1>
|
||||
<!-- Main Title - Kinetic Typography -->
|
||||
<h1 class="hero-title kinetic-title">
|
||||
{titleWords.map((word, index) => (
|
||||
<span class="word-wrapper">
|
||||
<span
|
||||
class="word"
|
||||
style={`--delay: ${0.4 + index * 0.12}s`}
|
||||
>
|
||||
{word}
|
||||
</span>
|
||||
</span>
|
||||
))}
|
||||
</h1>
|
||||
|
||||
<!-- Accent Line -->
|
||||
<div class="hero-accent-line">
|
||||
<div class="accent-fill"></div>
|
||||
</div>
|
||||
<!-- Accent Line -->
|
||||
<div class="hero-accent-line">
|
||||
<div class="accent-fill"></div>
|
||||
</div>
|
||||
|
||||
<!-- Subtitle -->
|
||||
<p class="hero-subtitle" data-animate="fade-in-up">
|
||||
<Fragment set:html={subtitle} />
|
||||
</p>
|
||||
<!-- Subtitle -->
|
||||
<p class="hero-subtitle" data-animate="fade-in-up">
|
||||
<Fragment set:html={subtitle} />
|
||||
</p>
|
||||
|
||||
<!-- CTA Buttons -->
|
||||
{showCTA && (
|
||||
<div class="hero-actions" data-animate="fade-in-up">
|
||||
<a href={ctaLink} class="btn btn-primary btn-magnetic">
|
||||
<span class="btn-text">{ctaText}</span>
|
||||
<svg class="btn-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<slot name="hero-cta-secondary" />
|
||||
<!-- CTA Buttons -->
|
||||
{showCTA && (
|
||||
<div class="hero-actions" data-animate="fade-in-up">
|
||||
<a href={ctaLink} class="btn btn-primary btn-magnetic">
|
||||
<span class="btn-text">{ctaText}</span>
|
||||
<svg class="btn-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
|
||||
<path d="M5 12h14M12 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
<slot name="hero-cta-secondary" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<slot name="hero-trust" />
|
||||
</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>
|
||||
|
||||
<!-- Giant Background Typography -->
|
||||
@@ -274,7 +296,103 @@ const titleWords = title.split(' ');
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
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; }
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
|
||||
@@ -76,8 +76,8 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
|
||||
<Navigation />
|
||||
|
||||
<Hero
|
||||
badge="ที่ปรึกษาที่วางกลยุทธ์จากข้อมูล ไม่ใช่จากประสบการณ์ล้วน ๆ"
|
||||
title="เว็บขายไม่ได้ โฆษณาเปลือง งานซ้ำเติมคน — เราแก้ให้ตรงจุด"
|
||||
badge="เราจะช่วยคุณเพิ่มกำไร"
|
||||
title="เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"
|
||||
subtitle="รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กร เริ่มจากดูสถิติของคุณก่อน ไม่ใช่เดาว่าควรทำอะไร"
|
||||
>
|
||||
<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">
|
||||
<span class="section-badge">บริการของเรา</span>
|
||||
<h2 class="section-title">
|
||||
เริ่มจากอันที่ปวดที่สุด <span class="highlight">ค่อยขยายไปอันอื่น</span>
|
||||
เลือกบริการที่<span class="highlight">ตรงกับปัญหาของคุณ</span>
|
||||
</h2>
|
||||
<p class="section-desc">ไม่จำเป็นต้องทำทุกอย่างพร้อมกัน</p>
|
||||
</div>
|
||||
@@ -167,8 +167,8 @@ const featuredPortfolio = portfolio.filter(p => p.data.featured).slice(0, 4);
|
||||
objective: 'เพิ่มยอดขาย และความน่าเชื่อถือให้ธุรกิจ',
|
||||
},
|
||||
];
|
||||
// Equal 4x3 tiles (full width, 1 row)
|
||||
const span = 3;
|
||||
// 2x2 layout — each tile span 6 (6+6 per row, 2 rows)
|
||||
const span = 6;
|
||||
const surface = (['yellow', 'purple-soft', 'mint', 'soft'] as const)[i];
|
||||
const copy = tileCopy[i];
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user