Add animated background to all hero sections

- Homepage: 3 animated orbs, 8 floating particles, 3 moving lines
- Service pages: 2 animated orbs, 4 particles, 2 moving lines
- About page: 2 animated orbs, 3 particles, 2 moving lines
- Portfolio page: 2 animated orbs, 4 particles, 2 moving lines
- Blog page: 2 animated orbs, 4 particles, 2 moving lines

All animations use yellow (#fed400) glow effects on dark background
This commit is contained in:
Kunthawat Greethong
2026-05-22 12:40:57 +07:00
parent 494b50925e
commit b7787cc403
4 changed files with 354 additions and 0 deletions

View File

@@ -11,8 +11,20 @@ import Footer from '../components/Footer.astro';
HERO SECTION
============================================= -->
<section class="about-hero">
<!-- Animated Background -->
<div class="hero-bg">
<div class="hero-grid"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="particles">
<div class="particle p-1"></div>
<div class="particle p-2"></div>
<div class="particle p-3"></div>
</div>
<div class="lines">
<div class="line line-1"></div>
<div class="line line-2"></div>
</div>
</div>
<div class="container">
@@ -170,6 +182,7 @@ import Footer from '../components/Footer.astro';
.hero-bg {
position: absolute;
inset: 0;
overflow: hidden;
}
.hero-grid {
@@ -181,6 +194,73 @@ import Footer from '../components/Footer.astro';
background-size: 60px 60px;
}
/* Animated Orbs */
.orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
opacity: 0.4;
}
.orb-1 {
width: 300px;
height: 300px;
background: rgba(254, 212, 0, 0.3);
top: -50px;
right: 10%;
animation: orbFloat1 8s ease-in-out infinite;
}
.orb-2 {
width: 200px;
height: 200px;
background: rgba(254, 212, 0, 0.2);
bottom: 20%;
left: 5%;
animation: orbFloat2 10s ease-in-out infinite;
}
@keyframes orbFloat1 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-40px, 30px) scale(1.1); }
}
@keyframes orbFloat2 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(50px, -30px) scale(1.15); }
}
/* Particles */
.particles { position: absolute; inset: 0; overflow: hidden; }
.particle {
position: absolute;
width: 4px;
height: 4px;
background: #fed400;
border-radius: 50%;
opacity: 0;
}
.p-1 { top: 30%; left: 15%; animation: particleFloat 7s ease-in-out infinite; }
.p-2 { top: 50%; left: 75%; animation: particleFloat 8s ease-in-out infinite; animation-delay: 2s; }
.p-3 { top: 70%; left: 30%; animation: particleFloat 6s ease-in-out infinite; animation-delay: 1s; }
@keyframes particleFloat {
0% { opacity: 0; transform: translateY(50px) scale(0); }
20% { opacity: 0.8; }
80% { opacity: 0.8; }
100% { opacity: 0; transform: translateY(-50px) scale(1); }
}
/* Lines */
.lines { position: absolute; inset: 0; overflow: hidden; }
.line {
position: absolute;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(254, 212, 0, 0.3), transparent);
animation: lineMove 12s linear infinite;
}
.line-1 { width: 50%; top: 35%; left: -50%; animation-delay: 0s; }
.line-2 { width: 40%; top: 65%; left: -40%; animation-delay: 6s; }
@keyframes lineMove {
0% { left: -50%; }
100% { left: 110%; }
}
.hero-content {
position: relative;
z-index: 2;

View File

@@ -17,6 +17,18 @@ const sortedPosts = blogPosts.sort((a, b) => b.data.date.valueOf() - a.data.date
<section class="blog-hero">
<div class="hero-bg">
<div class="hero-grid"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="particles">
<div class="particle p-1"></div>
<div class="particle p-2"></div>
<div class="particle p-3"></div>
<div class="particle p-4"></div>
</div>
<div class="lines">
<div class="line line-1"></div>
<div class="line line-2"></div>
</div>
</div>
<div class="container">
@@ -143,8 +155,10 @@ const sortedPosts = blogPosts.sort((a, b) => b.data.date.valueOf() - a.data.date
.hero-bg {
position: absolute;
inset: 0;
overflow: hidden;
}
.hero-grid {
position: absolute;
inset: 0;
@@ -154,6 +168,71 @@ const sortedPosts = blogPosts.sort((a, b) => b.data.date.valueOf() - a.data.date
background-size: 60px 60px;
}
.orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
opacity: 0.4;
}
.orb-1 {
width: 300px;
height: 300px;
background: rgba(254, 212, 0, 0.3);
top: -50px;
right: 10%;
animation: orbFloat1 8s ease-in-out infinite;
}
.orb-2 {
width: 200px;
height: 200px;
background: rgba(254, 212, 0, 0.2);
bottom: 20%;
left: 5%;
animation: orbFloat2 10s ease-in-out infinite;
}
@keyframes orbFloat1 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-40px, 30px) scale(1.1); }
}
@keyframes orbFloat2 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(50px, -30px) scale(1.15); }
}
.particles { position: absolute; inset: 0; overflow: hidden; }
.particle {
position: absolute;
width: 4px;
height: 4px;
background: #fed400;
border-radius: 50%;
opacity: 0;
}
.p-1 { top: 30%; left: 15%; animation: particleFloat 7s ease-in-out infinite; }
.p-2 { top: 50%; left: 75%; animation: particleFloat 8s ease-in-out infinite; animation-delay: 2s; }
.p-3 { top: 70%; left: 30%; animation: particleFloat 6s ease-in-out infinite; animation-delay: 1s; }
.p-4 { top: 20%; left: 60%; animation: particleFloat 9s ease-in-out infinite; animation-delay: 3s; }
@keyframes particleFloat {
0% { opacity: 0; transform: translateY(50px) scale(0); }
20% { opacity: 0.8; }
80% { opacity: 0.8; }
100% { opacity: 0; transform: translateY(-50px) scale(1); }
}
.lines { position: absolute; inset: 0; overflow: hidden; }
.line {
position: absolute;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(254, 212, 0, 0.3), transparent);
animation: lineMove 12s linear infinite;
}
.line-1 { width: 50%; top: 35%; left: -50%; animation-delay: 0s; }
.line-2 { width: 40%; top: 65%; left: -40%; animation-delay: 6s; }
@keyframes lineMove {
0% { left: -50%; }
100% { left: 110%; }
}
.hero-content {
position: relative;
z-index: 2;

View File

@@ -14,6 +14,18 @@ import { portfolioItems } from '../data/portfolio';
<section class="portfolio-hero">
<div class="hero-bg">
<div class="hero-grid"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="particles">
<div class="particle p-1"></div>
<div class="particle p-2"></div>
<div class="particle p-3"></div>
<div class="particle p-4"></div>
</div>
<div class="lines">
<div class="line line-1"></div>
<div class="line line-2"></div>
</div>
</div>
<div class="container">
@@ -111,8 +123,10 @@ import { portfolioItems } from '../data/portfolio';
.hero-bg {
position: absolute;
inset: 0;
overflow: hidden;
}
.hero-grid {
position: absolute;
inset: 0;
@@ -122,6 +136,69 @@ import { portfolioItems } from '../data/portfolio';
background-size: 60px 60px;
}
.orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
opacity: 0.4;
}
.orb-1 {
width: 300px;
height: 300px;
background: rgba(254, 212, 0, 0.3);
top: -50px;
right: 10%;
animation: orbFloat1 8s ease-in-out infinite;
}
.orb-2 {
width: 200px;
height: 200px;
background: rgba(254, 212, 0, 0.2);
bottom: 20%;
left: 5%;
animation: orbFloat2 10s ease-in-out infinite;
}
@keyframes orbFloat1 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-40px, 30px) scale(1.1); }
}
@keyframes orbFloat2 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(50px, -30px) scale(1.15); }
}
.particles { position: absolute; inset: 0; overflow: hidden; }
.particle {
position: absolute;
width: 4px;
height: 4px;
background: #fed400;
border-radius: 50%;
opacity: 0;
}
.p-1 { top: 30%; left: 15%; animation: particleFloat 7s ease-in-out infinite; }
.p-2 { top: 50%; left: 75%; animation: particleFloat 8s ease-in-out infinite; animation-delay: 2s; }
.p-3 { top: 70%; left: 30%; animation: particleFloat 6s ease-in-out infinite; animation-delay: 1s; }
.p-4 { top: 20%; left: 60%; animation: particleFloat 9s ease-in-out infinite; animation-delay: 3s; }
@keyframes particleFloat {
0% { opacity: 0; transform: translateY(50px) scale(0); }
20% { opacity: 0.8; }
80% { opacity: 0.8; }
100% { opacity: 0; transform: translateY(-50px) scale(1); }
}
.lines { position: absolute; inset: 0; overflow: hidden; }
.line {
position: absolute;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(254, 212, 0, 0.3), transparent);
animation: lineMove 12s linear infinite;
}
.line-1 { width: 50%; top: 35%; left: -50%; animation-delay: 0s; }
.line-2 { width: 40%; top: 65%; left: -40%; animation-delay: 6s; }
@keyframes lineMove {
0% { left: -50%; }
100% { left: 110%; }
}
.hero-content {
position: relative;
z-index: 2;

View File

@@ -149,6 +149,24 @@ const data = serviceData[slug] || serviceData['webdev'];
HERO SECTION - CLEAN DESIGN
============================================= -->
<section class="service-hero">
<!-- Animated Background -->
<div class="hero-bg">
<div class="hero-grid"></div>
<div class="hero-gradient"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="particles">
<div class="particle p-1"></div>
<div class="particle p-2"></div>
<div class="particle p-3"></div>
<div class="particle p-4"></div>
</div>
<div class="lines">
<div class="line line-1"></div>
<div class="line line-2"></div>
</div>
</div>
<div class="container">
<div class="hero-content">
<div class="hero-badge">
@@ -448,16 +466,116 @@ const data = serviceData[slug] || serviceData['webdev'];
SERVICE HERO - CLEAN DESIGN
============================================= */
/* =============================================
SERVICE HERO - CLEAN DESIGN
============================================= */
.service-hero {
background: #0F172A;
padding: 140px 0 100px;
position: relative;
overflow: hidden;
}
.hero-bg {
position: absolute;
inset: 0;
overflow: hidden;
}
.hero-grid {
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(254, 212, 0, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(254, 212, 0, 0.03) 1px, transparent 1px);
background-size: 60px 60px;
}
.hero-gradient {
position: absolute;
inset: 0;
background: radial-gradient(ellipse at 50% 0%, rgba(254, 212, 0, 0.1) 0%, transparent 50%);
}
/* Animated Orbs */
.orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
opacity: 0.4;
}
.orb-1 {
width: 300px;
height: 300px;
background: rgba(254, 212, 0, 0.3);
top: -50px;
right: 10%;
animation: orbFloat1 8s ease-in-out infinite;
}
.orb-2 {
width: 200px;
height: 200px;
background: rgba(254, 212, 0, 0.2);
bottom: 20%;
left: 5%;
animation: orbFloat2 10s ease-in-out infinite;
}
@keyframes orbFloat1 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(-40px, 30px) scale(1.1); }
}
@keyframes orbFloat2 {
0%, 100% { transform: translate(0, 0) scale(1); }
50% { transform: translate(50px, -30px) scale(1.15); }
}
/* Particles */
.particles { position: absolute; inset: 0; overflow: hidden; }
.particle {
position: absolute;
width: 4px;
height: 4px;
background: #fed400;
border-radius: 50%;
opacity: 0;
}
.p-1 { top: 30%; left: 15%; animation: particleFloat 7s ease-in-out infinite; }
.p-2 { top: 50%; left: 75%; animation: particleFloat 8s ease-in-out infinite; animation-delay: 2s; }
.p-3 { top: 70%; left: 30%; animation: particleFloat 6s ease-in-out infinite; animation-delay: 1s; }
.p-4 { top: 20%; left: 60%; animation: particleFloat 9s ease-in-out infinite; animation-delay: 3s; }
@keyframes particleFloat {
0% { opacity: 0; transform: translateY(50px) scale(0); }
20% { opacity: 0.8; }
80% { opacity: 0.8; }
100% { opacity: 0; transform: translateY(-50px) scale(1); }
}
/* Lines */
.lines { position: absolute; inset: 0; overflow: hidden; }
.line {
position: absolute;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(254, 212, 0, 0.3), transparent);
animation: lineMove 12s linear infinite;
}
.line-1 { width: 50%; top: 35%; left: -50%; animation-delay: 0s; }
.line-2 { width: 40%; top: 65%; left: -40%; animation-delay: 6s; }
@keyframes lineMove {
0% { left: -50%; }
100% { left: 110%; }
}
.service-hero .container {
display: grid;
grid-template-columns: 1.2fr 0.8fr;
gap: 60px;
align-items: start;
position: relative;
z-index: 2;
}
.hero-content {