Before: .tile-link-overlay contained the .mega-cta text. Both overlay and .mega-objective were positioned at the bottom of the tile, causing visual overlap. After: .mega-cta is a normal-flow <span> in tile-body (pushed to bottom via margin-top: auto). .tile-link-overlay is now an empty click target (no inner content, no padding, no flex).
601 lines
25 KiB
Plaintext
601 lines
25 KiB
Plaintext
---
|
|
import Base from '../layouts/Base.astro';
|
|
import Navigation from '../components/Navigation.astro';
|
|
import Footer from '../components/Footer.astro';
|
|
import Hero from '../components/Hero.astro';
|
|
import BentoGrid from '../components/BentoGrid.astro';
|
|
import BentoTile from '../components/BentoTile.astro';
|
|
import DecoOrb from '../components/DecoOrb.astro';
|
|
import { getCollection } from 'astro:content';
|
|
import PortfolioCard from '../components/PortfolioCard.astro';
|
|
|
|
// 4 problem cards (down from 12) — each has symptom + cause + how we fix it
|
|
const problemCards = [
|
|
{
|
|
icon: 'trendingDown',
|
|
title: 'ลงโฆษณาแล้วยอดไม่ขยับ',
|
|
symptom: 'คลิกเยอะ ยอดขายเท่าเดิม แต่คนที่ไม่ซื้อ',
|
|
cause: 'เลือกกลุ่มเป้าหมายผิด หรือยิงทุก Platform โดยไม่ดูว่าอันไหนคุ้ม',
|
|
fix: 'ดูสถิติ 3 เดือนย้อนหลัง แยกว่า Platform ไหน Convert ดี ตัดอันที่เสียเงินเปล่า? หรือ ถ้ายังไม่มีการวางระบบเก็บข้อมูล ก็จะวางระบบให้ ดังนั้นระยะยาวจะเห็นความแตกต่างแน่นอน',
|
|
example: 'เคส Dataroot: เพิ่ม Impression 373%, Click 114% โดยใช้งบน้อยลง 28% — ดูเคสเต็มใน Portfolio',
|
|
},
|
|
{
|
|
icon: 'shoppingCart',
|
|
title: 'เว็บมีคนเข้า แต่ไม่มีคนซื้อ',
|
|
symptom: 'Traffic เข้าพอสมควร แต่ไม่มีใครทัก ไม่มีใครโทร',
|
|
cause: 'เว็บสวยแต่ไม่ได้ออกแบบมาให้คนซื้อ หรือมีจุดติดขัดที่ทำให้คนออกก่อน',
|
|
fix: 'กรณีที่เว็บไม่มีการวางโค้ดเก็บสถิติ ก็จะวางระบบให้ ในกรณีที่มีระบบเก็บสถิติแล้ว ก็จะศึกษาสถิติ และดู Heatmap ว่าคนเข้ามาแล้วทำอะไร และปรับเว็บทีละจุด',
|
|
example: 'ลองคุยกัน เราจะดูให้ว่าเว็บคุณติดปัญหาตรงไหน',
|
|
},
|
|
{
|
|
icon: 'clipboard',
|
|
title: 'งานซ้ำ ๆ เสียเวลาเป็นชั่วโมงทุกวัน',
|
|
symptom: 'ทีมต้องคีย์ข้อมูล ทำรายงาน ตอบแชตเดิม ๆ จนไม่มีเวลาทำงานหลัก',
|
|
cause: 'ระบบไม่มีการเชื่อมกัน หรือยังทำ Manual อยู่',
|
|
fix: 'ดู Workflow ก่อน แล้วเลือกเครื่องมือที่เหมาะสม เช่น n8n, Script, หรือ AI ซึ่งจะช่วยลดเวลาจากชั่วโมงเป็นนาที หรือ อาจจะไม่ต้องให้พนักงานเสียเวลาอีกเลย เพราะระบบทำให้เองอัตโนมัติ',
|
|
example: 'ลองคุยกัน เราจะดู Workflow ให้ฟรี',
|
|
},
|
|
{
|
|
icon: 'brain',
|
|
title: 'ให้พนักงานใช้ AI แต่ไม่เห็นผลลัพธ์อย่างที่ต้องการ และยังมีค่าใช้จ่ายที่สูงเพิ่มแทน',
|
|
symptom: 'จ่ายแพง ใช้ AI ระดับ Frontier กับทุกงาน แต่ผลลัพธ์ไม่คุ้มเงิน',
|
|
cause: 'ใช้ AI ผิดแบบ — งานหลายอย่างใช้ Model ราคาถูกก็ได้ผลเท่า ๆ กัน หรือ พนักงานไม่เข้าใจสิ่งที่ AI จะช่วยงานจริง ทำให้ใช้งานผิดรูปแบบ',
|
|
fix: 'เลือกใช้ AI ให้ถูกกับงาน เพื่อประหยัดค่าใช้จ่าย รวมถึงให้ความรู้ หรือ วางระบบ AI Agent ให้มี skill เฉพาะทาง เพื่อช่วยพนักงาน ไม่ใช้ให้พนักงานใช้ AI โดยไม่มี skill พิเศษ',
|
|
example: 'AI Audit ฟรี — บอกได้ว่าควรใช้ AI ตัวไหน',
|
|
},
|
|
];
|
|
|
|
// Surface color rotation for the 4 problem cards — keep variety
|
|
const problemSurfaces = ['yellow', 'purple-soft', 'mint', 'soft'] as const;
|
|
|
|
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 featuredPortfolio = portfolio.filter(p =>
|
|
['dataroot', 'jet-industries', 'tuanthong', 'lawyernoom'].includes(p.id)
|
|
).sort((a, b) => {
|
|
const order = ['dataroot', 'jet-industries', 'tuanthong', 'lawyernoom'];
|
|
return order.indexOf(a.id) - order.indexOf(b.id);
|
|
});
|
|
---
|
|
|
|
<Base title="MoreminiMore - ที่ปรึกษาเว็บ การตลาด และ AI สำหรับ SME ไทย">
|
|
<Navigation />
|
|
|
|
<Hero
|
|
badge="Moreminimore"
|
|
title="เราจะช่วยคุณเพิ่มกำไร"
|
|
subtitle="เราช่วยวางระบบงาน และใช้สถิติวางกลยุทธ์ทางการตลาด"
|
|
>
|
|
<a slot="hero-cta-secondary" href="/portfolio" class="btn btn-outline-dark">
|
|
ดูผลงานจริง
|
|
</a>
|
|
</Hero>
|
|
|
|
<!-- PROBLEM SECTION — Bento layout (4 cards, varied spans) -->
|
|
<section class="section section-bento">
|
|
<DecoOrb color="yellow" size="500px" speed={0.4} position={{ top: '-150px', left: '-150px' }} opacity={0.25} blur="80px" />
|
|
<DecoOrb color="soft" size="400px" speed={0.3} position={{ bottom: '-100px', right: '-100px' }} opacity={0.4} blur="80px" />
|
|
<div class="container" style="position: relative; z-index: 1;">
|
|
<div class="section-header reveal">
|
|
<span class="section-badge">4 ปัญหาที่เจอบ่อยที่สุด</span>
|
|
<h2 class="section-title">
|
|
แต่ละปัญหา<span class="highlight">มีวิธีแก้ที่ต่างกัน</span>
|
|
</h2>
|
|
<p class="section-desc">เราไม่ได้บอกว่า "เราทำได้หมด" แต่บอกว่า "ถ้าเป็นแบบนี้ ทำแบบนี้"</p>
|
|
</div>
|
|
|
|
<BentoGrid>
|
|
{problemCards.map((card, i) => (
|
|
<BentoTile span={6} surface={problemSurfaces[i]} eyebrow={`ปัญหา ${String(i + 1).padStart(2, '0')}`} title={card.title}>
|
|
<div class="problem-section">
|
|
<span class="problem-label">อาการ</span>
|
|
<p class="problem-text">{card.symptom}</p>
|
|
</div>
|
|
|
|
<div class="problem-section">
|
|
<span class="problem-label">สาเหตุส่วนใหญ่</span>
|
|
<p class="problem-text">{card.cause}</p>
|
|
</div>
|
|
|
|
<div class="problem-fix">
|
|
<span class="problem-label problem-label-fix">เราแก้ยังไง</span>
|
|
<p class="problem-text">{card.fix}</p>
|
|
</div>
|
|
|
|
<div class="problem-example">
|
|
<span class="problem-example-icon">▸</span> {card.example}
|
|
</div>
|
|
</BentoTile>
|
|
))}
|
|
</BentoGrid>
|
|
|
|
<p class="problem-closing reveal">
|
|
ไม่แน่ใจว่าตรงกับข้อไหน — <a href="/contact" class="closing-link">นัดคุย 30 นาทีฟรี</a> เราจะช่วยดู
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- SERVICES SECTION — Bento layout (4 services, asymmetric) -->
|
|
<section class="section section-bento">
|
|
<DecoOrb color="purple" size="500px" speed={0.4} position={{ top: '-200px', right: '-150px' }} opacity={0.2} blur="100px" />
|
|
<DecoOrb color="yellow" size="400px" speed={0.3} position={{ bottom: '-100px', left: '-100px' }} opacity={0.25} blur="80px" />
|
|
<div class="container" style="position: relative; z-index: 1;">
|
|
<div class="section-header reveal">
|
|
<span class="section-badge">บริการของเรา</span>
|
|
<h2 class="section-title">
|
|
เลือกบริการที่<span class="highlight">ตรงกับปัญหาของคุณ</span>
|
|
</h2>
|
|
<p class="section-desc">ไม่จำเป็นต้องทำทุกอย่างพร้อมกัน</p>
|
|
</div>
|
|
|
|
<BentoGrid>
|
|
{dedupedServices.slice(0, 4).map((s, i) => {
|
|
// Tile-specific copy overrides (per user spec)
|
|
const tileCopy = [
|
|
{
|
|
eyebrow: 'ที่ปรึกษาด้าน AI',
|
|
surface: 'teal',
|
|
subtitle: 'การนำ AI มาปรับใช้ในองค์กร เพื่อลดต้นทุนและเวลา รวมถึงการรักษาความรู้จากพนักงานที่เชี่ยวชาญ',
|
|
objective: 'รักษาความรู้ขององค์กร ลดต้นทุนและเวลาการทำงาน',
|
|
bullets: [
|
|
'วิเคราะห์ workflow ที่เหมาะกับ AI ก่อนลงทุน',
|
|
'เลือก AI Model ที่คุ้มค่า ไม่ใช่แพงสุด',
|
|
'วางระบบ AI Agent ที่พนักงานใช้จริง',
|
|
],
|
|
},
|
|
{
|
|
eyebrow: 'วางระบบ Automation',
|
|
surface: 'coral',
|
|
subtitle: 'การออกแบบระบบ Automation สำหรับธุรกิจคุณโดยเฉพาะ',
|
|
objective: 'ลดต้นทุนและเวลา',
|
|
bullets: [
|
|
'ดู Workflow ก่อน เลือกเครื่องมือที่เหมาะสม',
|
|
'ลดเวลางานซ้ำจากชั่วโมงเป็นนาที',
|
|
'ระบบทำงานอัตโนมัติ พนักงานไม่เสียเวลาทำ Manual',
|
|
],
|
|
},
|
|
{
|
|
eyebrow: 'ที่ปรึกษาการตลาดออนไลน์',
|
|
surface: 'dark',
|
|
subtitle: 'ออกแบบและวางกลยุทธ์ตามสถิติ กลุ่มเป้าหมาย และการทำงานขององค์กรคุณ',
|
|
objective: 'เพิ่มยอดขาย',
|
|
bullets: [
|
|
'วางกลยุทธ์จากสถิติกลุ่มเป้าหมาย ไม่ใช่เดา',
|
|
'ดู Platform ที่ Convert ดี ตัดอันที่เสียเงินเปล่า',
|
|
'ระบบเก็บข้อมูล + วิเคราะห์ผล ค่อย ๆ ปรับ',
|
|
],
|
|
},
|
|
{
|
|
eyebrow: 'พัฒนาเว็บไซต์',
|
|
surface: 'purple',
|
|
subtitle: 'พัฒนาเว็บไซต์ที่สร้างผลลัพธ์ได้จริง สวยงาม และลูกค้าสามารถดูแลได้เอง',
|
|
objective: 'เพิ่มยอดขาย และความน่าเชื่อถือให้ธุรกิจ',
|
|
bullets: [
|
|
'เว็บที่ขายได้ + ลูกค้าดูแลเอง ไม่ต้องพึ่งเราทุกครั้ง',
|
|
'ออกแบบ SEO + GEO ให้ติดทั้ง Google และ AI Search',
|
|
'เลือก Tech Stack ที่เหมาะกับธุรกิจ ไม่ใช่ของถูกแต่พังบ่อย',
|
|
],
|
|
},
|
|
];
|
|
// 2x2 layout — each tile span 6 (6+6 per row, 2 rows)
|
|
const span = 6;
|
|
const copy = tileCopy[i];
|
|
const surface = copy.surface;
|
|
return (
|
|
<BentoTile span={span} surface={surface} eyebrow={copy.eyebrow} title={s.data.title}>
|
|
<p class="mega-subtitle">{copy.subtitle}</p>
|
|
<ul class="mega-bullets">
|
|
{copy.bullets.map(b => <li>{b}</li>)}
|
|
</ul>
|
|
<div class="mega-objective">
|
|
<span class="objective-label">เป้าหมาย:</span>
|
|
<span class="objective-value">{copy.objective}</span>
|
|
</div>
|
|
<span class="mega-cta">ดูรายละเอียด →</span>
|
|
<a href={`/services/${s.id}`} class="tile-link-overlay" aria-label={`ดูรายละเอียด ${s.data.title}`}></a>
|
|
</BentoTile>
|
|
);
|
|
})}
|
|
</BentoGrid>
|
|
|
|
<div class="section-cta">
|
|
<a href="/services" class="btn btn-dark btn-lg">ดูบริการทั้งหมด →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- PULL QUOTE -->
|
|
<section class="section section-dark-quote reveal">
|
|
<div class="container">
|
|
<blockquote class="pull-quote">
|
|
<p class="quote-text">
|
|
"เป้าหมายของเราคือ <span class="highlight">กำไรที่มากขึ้นของลูกค้า</span>"
|
|
</p>
|
|
<cite class="quote-author">— มอร์มินิมอร์</cite>
|
|
</blockquote>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- PORTFOLIO PREVIEW — featured real cases (filtered: must have url) -->
|
|
<section class="section section-soft">
|
|
<div class="container">
|
|
<div class="section-header reveal">
|
|
<span class="section-badge">ผลงานจริง ไม่ใช่ Mockup</span>
|
|
<h2 class="section-title">
|
|
ลูกค้าจริง <span class="highlight">เว็บจริง</span>
|
|
</h2>
|
|
<p class="section-desc">คลิกเข้าไปดูเว็บจริงที่ใช้งานอยู่ทุกวันนี้</p>
|
|
</div>
|
|
|
|
<div class="portfolio-preview-grid stagger-children">
|
|
{featuredPortfolio.filter(p => p.data.url).slice(0, 4).map((item) => (
|
|
<PortfolioCard
|
|
name={item.data.name}
|
|
url={item.data.url}
|
|
category={item.data.category}
|
|
category_label={item.data.category_label}
|
|
industry={item.data.industry}
|
|
thumbnail={item.data.thumbnail}
|
|
description={item.data.description}
|
|
what_we_did={item.data.what_we_did}
|
|
result={item.data.result}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<div class="section-cta">
|
|
<a href="/portfolio" class="btn btn-dark btn-lg">ดูผลงานทั้งหมด →</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FINAL CTA -->
|
|
<section class="section section-yellow cta-section">
|
|
<div class="container">
|
|
<div class="cta-content reveal">
|
|
<h2 class="cta-title">คุยกันก่อน 30 นาที ฟรี</h2>
|
|
<p class="cta-desc">เราจะแนะนำแนวทางเบื้องต้นให้คุณว่าควรเริ่มจากตรงไหน — จะบอกตรง ๆ ว่าอะไรควรทำหรือไม่ควรทำ</p>
|
|
<div class="cta-actions">
|
|
<a href="/contact" class="btn btn-dark btn-lg">
|
|
นัดคุย 30 นาที
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M5 12h14M12 5l7 7-7 7"/>
|
|
</svg>
|
|
</a>
|
|
<a href="https://line.me/ti/p/~@539hdlul" target="_blank" rel="noopener" class="btn btn-outline-dark btn-lg">
|
|
ทัก LINE: @moreminimore
|
|
</a>
|
|
</div>
|
|
<p class="cta-reassurance">ไม่มี commitment · ไม่มี script sales · พูดตรง ๆ</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<Footer />
|
|
</Base>
|
|
|
|
<style>
|
|
.section-bento {
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ============================================
|
|
PROBLEM TILES (inside BentoTile)
|
|
============================================ */
|
|
.problem-section {
|
|
margin-bottom: 14px;
|
|
}
|
|
.problem-fix {
|
|
background: rgba(255, 220, 0, 0.25);
|
|
border-left: 3px solid var(--color-black);
|
|
padding: 12px 14px;
|
|
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
|
margin: 14px -14px;
|
|
}
|
|
.surface-purple-soft .problem-fix,
|
|
.surface-mint .problem-fix,
|
|
.surface-soft .problem-fix {
|
|
background: rgba(0, 0, 0, 0.05);
|
|
border-left-color: var(--color-black);
|
|
}
|
|
.problem-label {
|
|
display: block;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1.5px;
|
|
margin-bottom: 6px;
|
|
opacity: 0.7;
|
|
}
|
|
.surface-yellow .problem-label { color: var(--color-black); opacity: 0.7; }
|
|
.problem-label-fix { color: var(--color-black); opacity: 1; }
|
|
.problem-text {
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
margin: 0;
|
|
}
|
|
.surface-yellow .problem-text { color: var(--color-black); }
|
|
.surface-purple-soft .problem-text,
|
|
.surface-mint .problem-text,
|
|
.surface-soft .problem-text { color: var(--color-gray-700); }
|
|
.problem-example {
|
|
margin-top: 16px;
|
|
padding-top: 16px;
|
|
border-top: 1px dashed currentColor;
|
|
opacity: 0.7;
|
|
font-size: 13px;
|
|
line-height: 1.5;
|
|
font-style: italic;
|
|
}
|
|
.problem-example-icon {
|
|
font-style: normal;
|
|
font-weight: 700;
|
|
margin-right: 4px;
|
|
}
|
|
.problem-closing {
|
|
text-align: center;
|
|
margin-top: 48px;
|
|
font-size: 17px;
|
|
color: var(--color-gray-700);
|
|
}
|
|
.closing-link {
|
|
color: var(--color-primary-dark);
|
|
font-weight: 700;
|
|
text-decoration: underline;
|
|
text-underline-offset: 3px;
|
|
}
|
|
|
|
/* ============================================
|
|
SERVICES TILES (inside BentoTile)
|
|
============================================ */
|
|
.mega-subtitle {
|
|
font-size: 15px;
|
|
line-height: 1.6;
|
|
margin-bottom: 16px;
|
|
}
|
|
.surface-yellow .mega-subtitle { color: var(--color-black); opacity: 0.85; }
|
|
.surface-purple-soft .mega-subtitle { color: var(--color-black); }
|
|
.surface-soft .mega-subtitle { color: var(--color-gray-700); }
|
|
|
|
/* Bullet list for service tiles */
|
|
.mega-bullets {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin-bottom: 20px;
|
|
}
|
|
.mega-bullets li {
|
|
position: relative;
|
|
padding-left: 20px;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
margin-bottom: 8px;
|
|
}
|
|
.mega-bullets li::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 9px;
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
background: currentColor;
|
|
opacity: 0.4;
|
|
}
|
|
|
|
/* Light text on dark service tiles */
|
|
.surface-teal .mega-subtitle,
|
|
.surface-teal .mega-bullets,
|
|
.surface-teal .mega-bullets li::before,
|
|
.surface-coral .mega-subtitle,
|
|
.surface-coral .mega-bullets,
|
|
.surface-coral .mega-bullets li::before,
|
|
.surface-dark .mega-subtitle,
|
|
.surface-dark .mega-bullets,
|
|
.surface-dark .mega-bullets li::before,
|
|
.surface-purple .mega-subtitle,
|
|
.surface-purple .mega-bullets,
|
|
.surface-purple .mega-bullets li::before {
|
|
color: rgba(255, 255, 255, 0.95);
|
|
}
|
|
.surface-soft .mega-subtitle { color: var(--color-gray-700); }
|
|
.mega-objective {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 14px;
|
|
background: rgba(0, 0, 0, 0.05);
|
|
border-radius: var(--radius-md);
|
|
margin-bottom: 20px;
|
|
}
|
|
.surface-yellow .mega-objective { background: rgba(0, 0, 0, 0.1); }
|
|
.objective-label {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
opacity: 0.7;
|
|
}
|
|
.objective-value {
|
|
font-size: 13px;
|
|
font-weight: 700;
|
|
}
|
|
.surface-yellow .objective-value { color: var(--color-black); }
|
|
.mega-cta {
|
|
display: inline-block;
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
text-decoration: none;
|
|
transition: transform 0.2s ease;
|
|
}
|
|
.bento-tile:hover .mega-cta { transform: translateX(4px); }
|
|
|
|
/* ============================================
|
|
PORTFOLIO PREVIEW
|
|
============================================ */
|
|
.portfolio-preview-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 20px;
|
|
max-width: 900px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* ============================================
|
|
SECTION UTILITIES
|
|
============================================ */
|
|
.section-header { margin-bottom: 40px; }
|
|
.section-cta {
|
|
text-align: center;
|
|
margin-top: 48px;
|
|
}
|
|
|
|
/* ============================================
|
|
PULL QUOTE — dark band
|
|
============================================ */
|
|
.section-dark-quote {
|
|
background: var(--color-black);
|
|
padding: 100px 0;
|
|
}
|
|
.pull-quote {
|
|
text-align: center;
|
|
max-width: 1000px;
|
|
margin: 0 auto;
|
|
}
|
|
.quote-text {
|
|
font-family: var(--font-display);
|
|
font-size: clamp(28px, 4.5vw, 52px);
|
|
font-weight: 800;
|
|
line-height: 1.25;
|
|
color: var(--color-white);
|
|
margin-bottom: 24px;
|
|
}
|
|
.quote-text .highlight {
|
|
color: var(--color-primary);
|
|
}
|
|
.quote-author {
|
|
font-style: normal;
|
|
font-size: 13px;
|
|
color: var(--color-gray-400);
|
|
text-transform: uppercase;
|
|
letter-spacing: 3px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ============================================
|
|
FINAL CTA — yellow section
|
|
============================================ */
|
|
.cta-section {
|
|
background: var(--color-primary);
|
|
padding: 100px 0;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
.cta-section::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: -50%;
|
|
right: -10%;
|
|
width: 600px;
|
|
height: 600px;
|
|
background: var(--color-primary-dark);
|
|
border-radius: 50%;
|
|
opacity: 0.4;
|
|
z-index: 0;
|
|
}
|
|
.cta-section::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -30%;
|
|
left: -5%;
|
|
width: 400px;
|
|
height: 400px;
|
|
background: var(--color-primary-dark);
|
|
border-radius: 50%;
|
|
opacity: 0.3;
|
|
z-index: 0;
|
|
}
|
|
.cta-content {
|
|
text-align: center;
|
|
max-width: 720px;
|
|
margin: 0 auto;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
.cta-title {
|
|
font-family: var(--font-display);
|
|
font-size: clamp(32px, 5vw, 52px);
|
|
font-weight: 900;
|
|
color: var(--color-black);
|
|
margin-bottom: 20px;
|
|
line-height: 1.15;
|
|
}
|
|
.cta-desc {
|
|
font-size: 18px;
|
|
color: var(--color-black);
|
|
opacity: 0.8;
|
|
margin-bottom: 36px;
|
|
line-height: 1.6;
|
|
}
|
|
.cta-actions {
|
|
display: flex;
|
|
gap: 16px;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 20px;
|
|
}
|
|
.cta-actions .btn svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
margin-left: 4px;
|
|
}
|
|
.cta-reassurance {
|
|
font-size: 14px;
|
|
color: var(--color-black);
|
|
opacity: 0.7;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* ============================================
|
|
RESPONSIVE
|
|
============================================ */
|
|
@media (max-width: 1024px) {
|
|
.portfolio-preview-grid { grid-template-columns: 1fr; max-width: 500px; }
|
|
}
|
|
@media (max-width: 640px) {
|
|
.cta-actions { flex-direction: column; }
|
|
.cta-actions .btn { width: 100%; justify-content: center; }
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Parallax orbs (use data-parallax-speed from DecoOrb)
|
|
const parallaxEls = document.querySelectorAll('[data-parallax-speed]');
|
|
function updateParallax() {
|
|
const scrolled = window.scrollY;
|
|
parallaxEls.forEach(el => {
|
|
const speed = parseFloat(el.getAttribute('data-parallax-speed') || '0.4');
|
|
const ty = scrolled * speed * -0.3;
|
|
el.style.transform = `translate3d(0, ${ty}px, 0)`;
|
|
});
|
|
}
|
|
window.addEventListener('scroll', () => requestAnimationFrame(updateParallax), { passive: true });
|
|
</script>
|