feat(about): Bento Grid layout + 7 content updates

Layout redesign:
- Add BentoGrid, BentoTile, DecoOrb components
- Add accent palette (purple/teal/mint/coral) to global tokens
- Rewrite about.astro using Bento Grid (12-col, surface variants)
- Decorative parallax blur orbs in 4 sections
- Value/process tiles use numerals 01-04 instead of emoji

Content updates per user feedback:
- Remove "Soloprenuer" emphasis
- Remove TOC ("เนื้อหาในหน้านี้") — not needed for short content
- Outsource + bot acknowledged as part of approach
- Replace AI stack with marketing intelligence tools
  (ad spy, SEO gap, trend tracking)
- No fabricated stat numbers — placeholders show "—"
  (only "5+ ปี" kept as verifiable, founded 2020)
- Post-delivery: small changes free, charge only for new features
- No Sprint methodology — flexible timeline, demo when ready

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Kunthawat Greethong
2026-06-08 19:06:55 +07:00
parent ca7f99ed41
commit 789473271e
6 changed files with 580 additions and 180 deletions

View File

@@ -3,7 +3,9 @@ import Base from '../layouts/Base.astro';
import Navigation from '../components/Navigation.astro';
import Footer from '../components/Footer.astro';
import PageHero from '../components/PageHero.astro';
import Icon from '../components/Icon.astro';
import BentoGrid from '../components/BentoGrid.astro';
import BentoTile from '../components/BentoTile.astro';
import DecoOrb from '../components/DecoOrb.astro';
import { getEntry, render } from 'astro:content';
import type { CollectionEntry } from 'astro:content';
@@ -20,18 +22,59 @@ const { Content } = await render(about);
subtitle="บริษัท มอร์มินิมอร์ จำกัด — นโยบายของเราคือสร้างระบบที่ทำให้ลูกค้ามีกำไรมากขึ้น ไม่ใช่ทำเว็บไซต์ออกมาเยอะแล้วลืม เราเป็น Partner ที่นั่งทำงานข้างคุณจนระบบติดและใช้งานได้จริง"
/>
<!-- ABOUT CONTENT (from about.md) -->
<section class="section">
<div class="container">
<article class="about-content">
<Content />
</article>
<!-- ABOUT CONTENT (BENTO) -->
<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;">
<BentoGrid>
<BentoTile span={12} surface="soft" eyebrow="นโยบายของเรา" title="เป้าหมายคือเพิ่มกำไรให้ลูกค้า">
<p>เพราะถ้าลูกค้ามีกำไรมากขึ้น ลูกค้าก็จะสามารถใช้บริการเราต่อไปได้</p>
<p>ทุกระบบที่ส่งมอบต้องตอบคำถามเดียวให้ได้: <strong>"ลูกค้ามีกำไรเพิ่มขึ้นจริงไหม"</strong> — ไม่ใช่แค่ส่งงานตามสัญญา</p>
</BentoTile>
<BentoTile span={8} surface="yellow" eyebrow="วิธีทำงานของเรา" title="ไม่ได้ทำงานแบบเดียวกับทุกที่">
<p>เพราะลูกค้าแต่ละคนมีบริบท งบประมาณ และทีมต่างกัน</p>
<ul class="checklist">
<li>✅ <strong>งานที่ต้องใช้ความเชี่ยวชาญเฉพาะทาง</strong> — เราทำเอง เพราะถ้าไม่ทำเอง จะตอบคำถามลูกค้าไม่ได้</li>
<li>✅ <strong>งานที่ต้องทำซ้ำ ๆ ปริมาณเยอะ</strong> — เราใช้ bot หรือ outsource ให้คนเชี่ยวชาญ เพราะคนที่ทำเป็นอาชีพจะดีกว่า</li>
<li>✅ <strong>งานที่ต้องตอบลูกค้าตลอด 24 ชั่วโมง</strong> — bot ช่วยคัดกรองเบื้องต้น แล้วเราตามด้วยคน</li>
</ul>
<p style="margin-top: 16px;"><strong>สรุป:</strong> ผลงานที่ออกมาขึ้นอยู่กับบริบทของลูกค้า ไม่ใช่วิธีทำงานของเรา — เราเลือกวิธีที่ทำให้ลูกค้าได้ผลลัพธ์ที่ดีที่สุด ไม่ใช่วิธีที่เราถนัดที่สุด</p>
</BentoTile>
<BentoTile span={4} surface="purple-soft" eyebrow="ปี 2020" title="ก่อตั้งจากประสบการณ์ตรง">
<p>เห็น SME ไทยเสียเงินหลายแสนไปกับเว็บไซต์ "สวยแต่ไม่มีคนเข้า" และ AI tools "ว้าวแต่ใช้ไม่เป็น"</p>
</BentoTile>
<BentoTile span={6} surface="mint" eyebrow="เราเชื่ออะไร" title="หลักคิด 6 ข้อ">
<ul>
<li>เว็บสวยไม่ได้แปลว่าขายได้</li>
<li>AI ไม่ได้แทนทุกอย่าง — แต่ถ้ารู้จักใช้...</li>
<li>จ่ายแพงไม่ได้แปลว่าดี</li>
<li>"สิ่งที่ถูกต้อง" ไม่ใช่ "สิ่งที่ลูกค้าต้องการ" เสมอไป</li>
<li>ระบบที่คนใช้ไม่เป็น = เสียเงินเปล่า</li>
</ul>
</BentoTile>
<BentoTile span={6} surface="teal" eyebrow="เบื้องหลัง" title="Marketing intelligence ที่ใช้">
<p>นั่งทำงานที่บ้าน ใช้ MacBook ตัวเดียว แต่มีเครื่องมือที่ช่วยให้เข้าใจตลาดได้ลึกกว่าคนทั่วไป:</p>
<ul>
<li><strong>ระบบดูโฆษณาคู่แข่ง</strong> — ดูว่าคู่แข่งยิงโฆษณาอะไร คำไหน convert ดี</li>
<li><strong>วิเคราะห์ keyword + SEO gap</strong> — หาโอกาสที่คู่แข่งยังไม่ได้ทำ</li>
<li><strong>ติดตาม trend ตลาด</strong> — รู้ก่อนลูกค้าว่าตลาดกำลังไปทางไหน</li>
</ul>
<p style="margin-top: 12px;"><strong>Stack:</strong> JavaScript, Python, PHP, n8n, OpenAI API, Meta API, Google Analytics, Looker Studio</p>
</BentoTile>
</BentoGrid>
</div>
</section>
<!-- STORY SECTION -->
<section class="section story-section">
<div class="container">
<section class="section section-bento">
<DecoOrb color="yellow" size="400px" speed={0.5} position={{ top: '10%', right: '-150px' }} opacity={0.3} blur="80px" />
<DecoOrb color="mint" size="300px" speed={0.3} position={{ bottom: '-100px', left: '-100px' }} opacity={0.2} blur="80px" />
<div class="container" style="position: relative; z-index: 1;">
<div class="story-grid">
<div class="story-content">
<span class="section-badge">นโยบายของเรา</span>
@@ -48,7 +91,7 @@ const { Content } = await render(about);
</p>
<p class="story-text">
<strong>ความต่างของเรา</strong> เราเขียนโค้ดเอง ไม่ใช่เอาไป Outsource เราตอบแชตเอง ไม่ใช่ใหBot ตอบลูกค้า เราวางแผนเอง ไม่ใช่ใช้ Template เดียวกับทุกคน
<strong>วิธีทำงานของเรา</strong> เราไม่ได้ทำงานแบบเดียวกับทุกที่ — งานที่ต้องใช้ความเชี่ยวชาญเฉพาะทางเราทำเอง งานที่ต้องทำซ้ำ ๆ ปริมาณเยอะเราใชbot หรือ outsource ให้คนเชี่ยวชาญราะคนที่ทำเป็นอาชีพจะดีกว่า
</p>
<div class="story-actions">
@@ -59,20 +102,20 @@ const { Content } = await render(about);
<div class="story-stats stagger-children">
<div class="stat-card">
<span class="stat-number counter" data-from="0">40+</span>
<span class="stat-number">—</span>
<span class="stat-label">ลูกค้าที่กลับมาใช้บริการซ้ำ</span>
</div>
<div class="stat-card">
<span class="stat-number counter" data-from="0">50+</span>
<span class="stat-number">—</span>
<span class="stat-label">โปรเจกต์ที่ส่งมอบ</span>
</div>
<div class="stat-card">
<span class="stat-number counter" data-from="0">5+</span>
<span class="stat-label">ปีของการทำงานหนัก</span>
<span class="stat-label">ปีของการทำงานหนัก (ก่อตั้งปี 2020)</span>
</div>
<div class="stat-card">
<span class="stat-number counter" data-from="0">100%</span>
<span class="stat-label">โค้ดโดยทีมเรา ไม่ Outsource</span>
<span class="stat-number">—</span>
<span class="stat-label">อุตสาหกรรมที่รับ</span>
</div>
</div>
</div>
@@ -81,7 +124,9 @@ const { Content } = await render(about);
<!-- VALUES SECTION (yellow accent cards on soft) -->
<section class="section section-soft values-section">
<div class="container">
<DecoOrb color="purple" size="500px" speed={0.4} position={{ top: '-200px', left: '20%' }} opacity={0.2} blur="100px" />
<DecoOrb color="soft" size="400px" speed={0.3} position={{ bottom: '-100px', right: '5%' }} opacity={0.4} 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">
@@ -90,33 +135,25 @@ const { Content } = await render(about);
</div>
<div class="values-grid stagger-children">
<div class="value-card">
<div class="value-icon">
<Icon name="target" />
</div>
<div class="value-card value-card-yellow">
<div class="value-num">01</div>
<h3 class="value-title">เข้าใจธุรกิจก่อนเขียนโค้ด</h3>
<p class="value-desc">30 นาทีแรกของทุกโปรเจกต์คือการถาม ไม่ใช่การ present เราถามจนเข้าใจว่าคุณขายให้ใคร กำไรเท่าไหร่ ปวดหัวตรงไหน แล้วค่อยแนะนำ solution</p>
</div>
<div class="value-card">
<div class="value-icon">
<Icon name="users" />
</div>
<div class="value-num">02</div>
<h3 class="value-title">เป็น Partner ไม่ใช่ Vendor</h3>
<p class="value-desc">เราแชร์ progress ทุกสัปดาห์ผ่าน LINE Group เดียวกับที่ลูกค้าใช้ คุณเห็นทุก decision ไม่มี hidden cost ไม่มี "อันนี้เพิ่มเงินนะ" ตอนใกล้ deliver</p>
</div>
<div class="value-card">
<div class="value-icon">
<Icon name="clock" />
</div>
<div class="value-num">03</div>
<h3 class="value-title">Deliver ตรงเวลา หรือบอกล่วงหน้า</h3>
<p class="value-desc">เราไม่สัญญา deadline แบบเลื่อนได้ ถ้าจะติด เราจะบอกก่อน 7 วัน ไม่ใช่บอกตอนส่งงาน เคสไหนที่เคยส่งช้า เราคืนเงิน Pro-rata</p>
</div>
<div class="value-card">
<div class="value-icon">
<Icon name="shield" />
</div>
<div class="value-num">04</div>
<h3 class="value-title">ดูแลหลังส่งมอบ</h3>
<p class="value-desc">เว็บไซต์ที่ส่งแล้วทิ้งเป็นเว็บตาย เราเลยมีแพ็คเกจดูแลรายเดือนเริ่ม 2,000 บาท รวมอัปเดตเนื้อหา ปรับ SEO แก้บั๊ก ตอบคำถามผ่าน LINE</p>
<p class="value-desc">ปรับเล็ก ๆ น้อย ๆ ฟรี — คิดค่าใช้จ่ายเฉพาะ feature ใหม่หรือปรับแต่งครั้งใหญ่เท่านั้น</p>
</div>
</div>
</div>
@@ -136,7 +173,9 @@ const { Content } = await render(about);
<!-- PROCESS SECTION (4 steps, white) -->
<section class="section process-section">
<div class="container">
<DecoOrb color="soft" size="600px" speed={0.4} position={{ top: '-150px', right: '-100px' }} opacity={0.5} blur="80px" />
<DecoOrb color="yellow" size="300px" speed={0.3} position={{ bottom: '5%', left: '-100px' }} opacity={0.3} 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">
@@ -146,7 +185,7 @@ const { Content } = await render(about);
</div>
<div class="process-grid stagger-children">
<div class="process-step">
<div class="process-step process-step-wide">
<span class="step-num">01</span>
<h3 class="step-title">ปรึกษาฟรี</h3>
<p class="step-desc">3060 นาทีคุยกับเจ้าของธุรกิจ ฟัง pain points, เป้าหมาย, budget ให้คำแนะนำเบื้องต้นฟรี ไม่ผูก commitment</p>
@@ -154,17 +193,19 @@ const { Content } = await render(about);
<div class="process-step">
<span class="step-num">02</span>
<h3 class="step-title">วางแผน</h3>
<p class="step-desc">วิเคราะห์เชิงลึก ดูคู่แข่ง ส่ง Proposal เป็นเอกสาร PDF คุณอ่าน ถามคำถาม แก้ไข scope ได้ก่อนเซ็น</p>
<p class="step-desc">วิเคราะห์เชิงลึก ดูคู่แข่ง ส่ง Proposal เป็น PDF คุณอ่าน ถามคำถาม แก้ไข scope ได้ก่อนเซ็น</p>
</div>
<div class="process-step">
<div class="process-step process-step-teal">
<span class="step-num">03</span>
<h3 class="step-title">ดำเนินการ</h3>
<p class="step-desc">พัฒนาแบบ Sprint ส่ง demo ให้ทดสอบทุก 714 วัน เห็นงานจริง ไม่ใช่ "เดี๋ยวส่งทีเดียวตอนจบ"</p>
<p class="step-desc">แจ้งความคืบหน้าเป็นช่วง ๆ ผ่าน LINE Group — demo เมื่อเราพร้อมส่งงานรอบใหญ่ ๆ ไม่ sprint ไม่ deadline ล็อก</p>
</div>
<div class="process-step">
<div class="process-step process-step-yellow process-step-full">
<span class="step-num">04</span>
<h3 class="step-title">สนับสนุน</h3>
<p class="step-desc">ส่งมอบงาน + อบรมทีม + มอบคู่มือ ติดตามผลทุกเดือน แนะนำสิ่งที่ควรปรับปรุง ต่อยอด หรือยกเลิก</p>
<div>
<h3 class="step-title">ส่งมอบ + ดูแล</h3>
<p class="step-desc">ส่งมอบงาน + อบรมทีม + มอบคู่มือ หลังส่งมอบปรับเล็ก ๆ น้อย ๆ ฟรี — คิดค่าใช้จ่ายเฉพาะ feature ใหม่หรือปรับแต่งครั้งใหญ่</p>
</div>
</div>
</div>
</div>
@@ -190,92 +231,125 @@ const { Content } = await render(about);
<style>
.section-soft { background: var(--color-bg-alt); }
.section-yellow { background: var(--color-primary); }
/* ABOUT CONTENT (from markdown) */
.about-content {
max-width: 760px;
margin: 0 auto;
font-size: 16px;
line-height: 1.8;
color: var(--color-gray-700);
.section-bento {
position: relative;
overflow: hidden;
}
.about-content :global(h1) {
/* VALUES (keep existing classes) */
.values-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24px;
max-width: 900px;
margin: 0 auto;
}
.value-card {
background: var(--color-white);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-xl);
padding: 32px;
transition: all 0.3s ease;
}
.value-card:hover {
border-color: var(--color-primary);
transform: translateY(-4px);
box-shadow: var(--shadow-md);
}
.value-num {
font-family: var(--font-display);
font-size: 36px;
font-size: 22px;
font-weight: 900;
color: var(--color-black);
margin-bottom: 24px;
width: 64px;
height: 64px;
border: 2px solid var(--color-black);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
letter-spacing: -1px;
}
.about-content :global(h2) {
.value-card-yellow { background: var(--color-primary); border-color: var(--color-primary); }
.value-card-yellow .value-num { background: var(--color-black); color: var(--color-primary); border-color: var(--color-black); }
.value-title {
font-family: var(--font-display);
font-size: 26px;
font-size: 18px;
font-weight: 800;
color: var(--color-black);
margin: 48px 0 16px;
padding-top: 24px;
border-top: 1px solid var(--color-gray-200);
margin-bottom: 10px;
}
.about-content :global(h3) {
.value-desc {
font-size: 14px;
color: var(--color-gray-700);
line-height: 1.6;
}
.value-card-yellow .value-desc { color: rgba(0, 0, 0, 0.85); }
/* PROCESS (asymmetric bento) */
.process-section { background: var(--color-bg-alt); position: relative; overflow: hidden; }
.process-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: minmax(160px, auto);
gap: 16px;
}
.process-step {
background: var(--color-white);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-xl);
padding: 32px;
transition: all 0.3s ease;
grid-column: span 3;
display: flex;
flex-direction: column;
justify-content: center;
}
.process-step-wide { grid-column: span 3; }
.process-step-full { grid-column: span 6; flex-direction: row; align-items: center; gap: 32px; }
.process-step-full .step-num { margin-bottom: 0; }
.process-step-teal { background: var(--color-teal); border-color: var(--color-teal); color: var(--color-white); }
.process-step-teal .step-num { color: var(--color-primary); }
.process-step-teal .step-title { color: var(--color-white); }
.process-step-teal .step-desc { color: rgba(255, 255, 255, 0.92); }
.process-step-yellow { background: var(--color-primary); border-color: var(--color-primary); }
.process-step-yellow .step-num { color: var(--color-black); }
.process-step:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-md);
}
.step-num {
display: block;
font-family: var(--font-display);
font-size: clamp(48px, 5vw, 64px);
font-weight: 900;
color: var(--color-primary);
line-height: 1;
margin-bottom: 12px;
}
.step-title {
font-family: var(--font-display);
font-size: 20px;
font-weight: 800;
color: var(--color-black);
margin: 32px 0 12px;
margin-bottom: 10px;
}
.about-content :global(p) {
margin-bottom: 16px;
}
.about-content :global(strong) {
color: var(--color-black);
font-weight: 700;
}
.about-content :global(blockquote) {
border-left: 4px solid var(--color-primary);
padding: 16px 20px;
margin: 24px 0;
background: var(--color-bg-alt);
border-radius: 0 var(--radius-md) var(--radius-md) 0;
font-style: italic;
}
.about-content :global(ul),
.about-content :global(ol) {
padding-left: 24px;
margin-bottom: 16px;
}
.about-content :global(li) {
margin-bottom: 8px;
}
.section-badge {
display: inline-block;
background: var(--color-primary);
color: var(--color-black);
padding: 8px 20px;
border-radius: var(--radius-full);
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 2px;
margin-bottom: 16px;
}
.section-title {
font-family: var(--font-display);
font-size: clamp(28px, 4vw, 44px);
font-weight: 900;
line-height: 1.15;
color: var(--color-black);
margin-bottom: 16px;
}
.section-title .highlight { color: var(--color-primary-dark); }
.section-desc {
font-size: 17px;
color: var(--color-gray-600);
.step-desc {
font-size: 15px;
color: var(--color-gray-700);
line-height: 1.6;
}
/* STORY */
.story-section { background: var(--color-white); }
@media (max-width: 1024px) {
.process-step, .process-step-wide { grid-column: span 6; }
}
@media (max-width: 640px) {
.process-step, .process-step-wide, .process-step-full { grid-column: span 6; flex-direction: column; align-items: flex-start; }
.values-grid { grid-template-columns: 1fr; }
}
/* STORY (keep existing) */
.story-grid {
display: grid;
grid-template-columns: 1.3fr 0.7fr;
@@ -302,7 +376,7 @@ const { Content } = await render(about);
}
.stat-card {
padding: 24px;
background: var(--color-bg-alt);
background: var(--color-bg-soft);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-xl);
transition: all 0.3s ease;
@@ -325,84 +399,35 @@ const { Content } = await render(about);
color: var(--color-gray-600);
margin-top: 8px;
}
/* VALUES — 2x2 grid for visual balance with 4 cards */
.values-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24px;
max-width: 900px;
margin: 0 auto;
}
.value-card {
background: var(--color-white);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-xl);
padding: 32px;
text-align: center;
transition: all 0.3s ease;
}
.value-card:hover {
border-color: var(--color-primary);
transform: translateY(-4px);
box-shadow: var(--shadow-md);
}
.value-icon { font-size: 40px; margin-bottom: 16px; }
.value-title {
font-family: var(--font-display);
font-size: 16px;
font-weight: 800;
.section-badge {
display: inline-block;
background: var(--color-primary);
color: var(--color-black);
margin-bottom: 10px;
padding: 8px 20px;
border-radius: var(--radius-full);
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 2px;
margin-bottom: 16px;
}
.value-desc {
font-size: 14px;
color: var(--color-gray-600);
line-height: 1.6;
}
/* PROCESS */
.process-section { background: var(--color-bg-alt); }
.process-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
}
.process-step {
background: var(--color-white);
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-xl);
padding: 32px;
transition: all 0.3s ease;
}
.process-step:hover {
border-color: var(--color-primary);
transform: translateY(-4px);
box-shadow: var(--shadow-md);
}
.step-num {
display: block;
.section-title {
font-family: var(--font-display);
font-size: 36px;
font-size: clamp(28px, 4vw, 44px);
font-weight: 900;
color: var(--color-primary);
line-height: 1;
margin-bottom: 12px;
}
.step-title {
font-family: var(--font-display);
font-size: 18px;
font-weight: 800;
line-height: 1.15;
color: var(--color-black);
margin-bottom: 10px;
margin-bottom: 16px;
}
.step-desc {
font-size: 14px;
.section-title .highlight { color: var(--color-primary-dark); }
.section-desc {
font-size: 17px;
color: var(--color-gray-600);
line-height: 1.6;
}
.section-header { text-align: center; margin-bottom: 48px; }
/* PULL QUOTE (dark band) */
/* PULL QUOTE */
.section-dark-quote {
background: var(--color-black);
padding: 100px 0;
@@ -452,15 +477,25 @@ const { Content } = await render(about);
flex-wrap: wrap;
}
/* RESPONSIVE */
@media (max-width: 1024px) {
.story-grid { grid-template-columns: 1fr; gap: 40px; }
.process-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
.story-actions, .cta-actions { flex-direction: column; }
.story-actions .btn, .cta-actions .btn { width: 100%; justify-content: center; }
.values-grid { grid-template-columns: 1fr; }
.process-grid { grid-template-columns: 1fr; }
}
</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>