premium
This commit is contained in:
parent
f044a14fa2
commit
3b6063d8c5
@ -2,3 +2,4 @@
|
|||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-12">
|
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-22">
|
||||||
<div class="text-center max-w-5xl mx-auto">
|
<div class="text-center max-w-5xl mx-auto">
|
||||||
<!-- Bismillah -->
|
<!-- Bismillah -->
|
||||||
<div class="mb-10 animate-fade-in-down">
|
<div class="mb-10 animate-fade-in-down">
|
||||||
@ -158,17 +158,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Decorative Element -->
|
<!-- Decorative Lanterns -->
|
||||||
<div class="absolute inset-0 pointer-events-none overflow-hidden">
|
<div class="absolute top-4 left-4 md:top-8 md:left-8 animate-sway">
|
||||||
<div class="absolute top-0 left-1/2 transform -translate-x-1/2">
|
<Lantern />
|
||||||
<svg viewBox="0 0 200 100" class="w-40 md:w-48 h-20 md:h-24 text-yellow-400 opacity-20">
|
|
||||||
<path
|
|
||||||
d="M100 20 Q120 0 140 20 Q160 40 140 60 Q120 40 100 60 Q80 40 60 60 Q40 40 60 20 Q80 0 100 20"
|
|
||||||
fill="currentColor"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="absolute top-4 right-4 md:top-8 md:right-8 animate-sway animation-delay-1000">
|
||||||
|
<Lantern />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Kubah Decorations -->
|
||||||
|
<div class="absolute top-0 left-8 md:left-32 w-14 md:w-34 kubah-swing animation-delay-300">
|
||||||
|
<img src="/kubah.png" alt="Kubah" class="w-full h-auto opacity-80" />
|
||||||
|
</div>
|
||||||
|
<div class="absolute top-0 right-8 md:right-22 w-14 md:w-44 kubah-swing animation-delay-600">
|
||||||
|
<img src="/kubah.png" alt="Kubah" class="w-full h-auto opacity-80" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -294,11 +298,16 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* Animations & bg-pattern */
|
/* =========================
|
||||||
|
🎨 Background Pattern
|
||||||
|
========================= */
|
||||||
.bg-pattern {
|
.bg-pattern {
|
||||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><pattern id='pattern' x='0' y='0' width='20' height='20' patternUnits='userSpaceOnUse'><path d='M10 5 L15 10 L10 15 L5 10 Z' fill='none' stroke='rgba(255,255,255,0.1)' stroke-width='0.5'/></pattern></defs><rect width='100' height='100' fill='url(%23pattern)'/></svg>");
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><pattern id='pattern' x='0' y='0' width='20' height='20' patternUnits='userSpaceOnUse'><path d='M10 5 L15 10 L10 15 L5 10 Z' fill='none' stroke='rgba(255,255,255,0.1)' stroke-width='0.5'/></pattern></defs><rect width='100' height='100' fill='url(%23pattern)'/></svg>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
✨ General Animations
|
||||||
|
========================= */
|
||||||
.animate-sway {
|
.animate-sway {
|
||||||
animation: sway 3s ease-in-out infinite;
|
animation: sway 3s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
@ -308,20 +317,37 @@ onUnmounted(() => {
|
|||||||
50% { transform: translateY(-10px); }
|
50% { transform: translateY(-10px); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
🕌 Smooth Kubah Swing
|
||||||
|
========================= */
|
||||||
|
.kubah-swing {
|
||||||
|
animation: kubahSwingSmooth 6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
|
||||||
|
transform-origin: top center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes kubahSwingSmooth {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
20% { transform: rotate(3deg); }
|
||||||
|
40% { transform: rotate(-3deg); }
|
||||||
|
60% { transform: rotate(3.5deg); }
|
||||||
|
80% { transform: rotate(-3deg); }
|
||||||
|
100% { transform: rotate(0deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
✨ Fade Animations
|
||||||
|
========================= */
|
||||||
.animate-fade-in-down {
|
.animate-fade-in-down {
|
||||||
animation: fadeInDown 1s ease-out forwards;
|
animation: fadeInDown 0.5s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-fade-in-up {
|
.animate-fade-in-up {
|
||||||
animation: fadeInUp 1s ease-out forwards;
|
animation: fadeInUp 0.5s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-fade-in-left {
|
.animate-fade-in-left {
|
||||||
animation: fadeInLeft 1s ease-out forwards;
|
animation: fadeInLeft 0.5s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-fade-in-right {
|
.animate-fade-in-right {
|
||||||
animation: fadeInRight 1s ease-out forwards;
|
animation: fadeInRight 0.5s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInDown {
|
@keyframes fadeInDown {
|
||||||
@ -344,19 +370,17 @@ onUnmounted(() => {
|
|||||||
to { opacity: 1; transform: translateX(0); }
|
to { opacity: 1; transform: translateX(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.animation-delay-300 {
|
/* =========================
|
||||||
animation-delay: 0.3s;
|
⏱️ Delay Utilities
|
||||||
}
|
========================= */
|
||||||
|
.animation-delay-300 { animation-delay: 0.3s; }
|
||||||
.animation-delay-600 {
|
.animation-delay-600 { animation-delay: 0.6s; }
|
||||||
animation-delay: 0.6s;
|
.animation-delay-1000 { animation-delay: 0.8s; }
|
||||||
}
|
|
||||||
|
|
||||||
.animation-delay-1000 {
|
|
||||||
animation-delay: 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
🕌 Font Arabic
|
||||||
|
========================= */
|
||||||
.arabic-text {
|
.arabic-text {
|
||||||
font-family: 'Noto Naskh Arabic', serif;
|
font-family: 'Noto Naskh Arabic', serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="relative z-10 flex flex-col items-center justify-center px-6 py-12">
|
<div class="relative z-10 flex flex-col items-center justify-center px-6 py-18">
|
||||||
<!-- Gallery Title -->
|
<!-- Gallery Title -->
|
||||||
<div class="text-center mb-8 animate-fade-in-down">
|
<div class="text-center mb-8 animate-fade-in-down">
|
||||||
<h1 class="text-yellow-400 text-4xl md:text-5xl font-bold mb-6 font-script">
|
<h1 class="text-yellow-400 text-4xl md:text-5xl font-bold mb-6 font-script">
|
||||||
@ -17,40 +17,20 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Photo Gallery Grid -->
|
<!-- ✅ Masonry-style Gallery -->
|
||||||
<div class="flex-1 max-w-4xl mx-auto w-full animate-fade-in-up animation-delay-300">
|
<div class="flex-1 max-w-5xl mx-auto w-full animate-fade-in-up animation-delay-300">
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div class="columns-2 md:columns-3 gap-4 space-y-4">
|
||||||
<!-- Foto pertama (besar) -->
|
|
||||||
<div
|
<div
|
||||||
v-if="images.length > 0"
|
v-for="(image, index) in images"
|
||||||
class="md:col-span-1 md:row-span-2 relative group cursor-pointer"
|
:key="index"
|
||||||
@click="openModal(0)"
|
class="relative group break-inside-avoid cursor-pointer"
|
||||||
|
@click="openModal(index)"
|
||||||
>
|
>
|
||||||
<div class="bg-white/10 backdrop-blur-sm rounded-2xl overflow-hidden border border-yellow-400/30 hover:border-yellow-400/60 transition-all duration-300">
|
<div class="bg-white/10 backdrop-blur-sm rounded-2xl overflow-hidden border border-yellow-400/30 hover:border-yellow-400/60 transition-all duration-300">
|
||||||
<img
|
|
||||||
:src="images[0]"
|
|
||||||
:alt="`Gallery Image 1`"
|
|
||||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
|
||||||
@error="handleImageError"
|
|
||||||
/>
|
|
||||||
<div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 flex items-center justify-center transition-colors duration-300">
|
|
||||||
<Icon name="lucide:zoom-in" class="w-8 h-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Foto lainnya -->
|
|
||||||
<div
|
|
||||||
v-for="(image, index) in images.slice(1)"
|
|
||||||
:key="index + 1"
|
|
||||||
class="relative group cursor-pointer"
|
|
||||||
@click="openModal(index + 1)"
|
|
||||||
>
|
|
||||||
<div class="bg-white/10 backdrop-blur-sm rounded-xl overflow-hidden border border-yellow-400/30 hover:border-yellow-400/60 transition-all duration-300">
|
|
||||||
<img
|
<img
|
||||||
:src="image"
|
:src="image"
|
||||||
:alt="`Gallery Image ${index + 2}`"
|
:alt="`Gallery Image ${index + 1}`"
|
||||||
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
class="w-full h-auto object-cover group-hover:scale-105 transition-transform duration-300"
|
||||||
@error="handleImageError"
|
@error="handleImageError"
|
||||||
/>
|
/>
|
||||||
<div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 flex items-center justify-center transition-colors duration-300">
|
<div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 flex items-center justify-center transition-colors duration-300">
|
||||||
@ -180,4 +160,9 @@ onUnmounted(() => {
|
|||||||
.bg-pattern {
|
.bg-pattern {
|
||||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="islamic" x="0" y="0" width="25" height="25" patternUnits="userSpaceOnUse"><g fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"><path d="M12.5 0 L25 12.5 L12.5 25 L0 12.5 Z M6.25 6.25 L18.75 6.25 L18.75 18.75 L6.25 18.75 Z"/><circle cx="12.5" cy="12.5" r="3"/></g></pattern></defs><rect width="100%" height="100%" fill="url(%23islamic)"/></svg>');
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="islamic" x="0" y="0" width="25" height="25" patternUnits="userSpaceOnUse"><g fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"><path d="M12.5 0 L25 12.5 L12.5 25 L0 12.5 Z M6.25 6.25 L18.75 6.25 L18.75 18.75 L6.25 18.75 Z"/><circle cx="12.5" cy="12.5" r="3"/></g></pattern></defs><rect width="100%" height="100%" fill="url(%23islamic)"/></svg>');
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
/* Masonry layout fix */
|
||||||
|
.break-inside-avoid {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
<!-- components/shared/GuestBook.vue -->
|
<!-- components/shared/GuestBook.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div class="h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-hidden">
|
<div class="min-h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-x-hidden overflow-y-auto">
|
||||||
|
|
||||||
<!-- Background Pattern -->
|
<!-- Background Pattern -->
|
||||||
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="relative z-10 h-full flex items-center justify-center px-6 py-12">
|
<div class="relative z-10 h-full flex items-center justify-center px-6 py-18">
|
||||||
<div class="w-full max-w-6xl mx-auto">
|
<div class="w-full max-w-6xl mx-auto">
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
|
|||||||
@ -2,7 +2,10 @@
|
|||||||
<div
|
<div
|
||||||
class="h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-hidden"
|
class="h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-hidden"
|
||||||
>
|
>
|
||||||
<!-- Main Content -->
|
<!-- Background Pattern -->
|
||||||
|
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-12">
|
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-12">
|
||||||
<div class="text-center max-w-4xl mx-auto">
|
<div class="text-center max-w-4xl mx-auto">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
@ -11,49 +14,44 @@
|
|||||||
Introduction
|
Introduction
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Background Pattern -->
|
<!-- Child Section -->
|
||||||
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
<div class="relative z-10 h-full flex flex-col items-center justify-center px-6 text-center">
|
||||||
|
<!-- Child Photo -->
|
||||||
|
<div class="w-68 h-80 overflow-hidden rounded-t-3xl mx-auto mb-[-20px] shadow-lg">
|
||||||
|
<img
|
||||||
|
:src="getFullPhotoUrl(childPhoto)"
|
||||||
|
alt="Child"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Child Name with nickname.png background (Tailwind version) -->
|
||||||
<div
|
<div
|
||||||
class="relative z-10 h-full flex flex-col items-center justify-center px-6 text-center"
|
class="relative mb-0 inline-flex items-center justify-center w-[420px] h-[110px] bg-[url('/nickname.png')] bg-contain bg-no-repeat bg-center"
|
||||||
>
|
>
|
||||||
<!-- Child Photo -->
|
<h1 class="text-yellow-400 font-bold text-xl md:text-2xl font-script drop-shadow-lg">
|
||||||
<div class="w-48 h-60 overflow-hidden rounded-t-3xl mx-auto mb-6 shadow-lg">
|
{{ form.nama_lengkap || 'Nama Anak' }}
|
||||||
<img
|
</h1>
|
||||||
:src="getFullPhotoUrl(childPhoto)"
|
</div>
|
||||||
alt="Child"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Child Name -->
|
|
||||||
<div
|
|
||||||
class="bg-blue-800/50 border border-yellow-400 rounded-md px-6 py-2 mb-4 inline-block"
|
|
||||||
>
|
|
||||||
<h1 class="text-yellow-400 font-bold text-xl">
|
|
||||||
{{ form.nama_lengkap || 'Nama Anak' }}
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Child Order -->
|
<!-- Child Order -->
|
||||||
<div v-if="form.anak_ke" class="text-white/80 text-lg mb-2">
|
<div v-if="form.anak_ke" class="text-white/80 text-lg mb-2">
|
||||||
Putra ke {{ form.anak_ke }} dari
|
Putra ke {{ form.anak_ke }} dari
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="text-white/80 text-lg mb-2">
|
<div v-else class="text-white/80 text-lg mb-2">
|
||||||
Putra dari
|
Putra dari
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Parents -->
|
<!-- Parents -->
|
||||||
<div class="text-yellow-400 font-semibold text-xl">
|
<div class="text-yellow-400 font-semibold text-xl">
|
||||||
{{ form.nama_bapak || 'Nama Ayah' }} & {{ form.nama_ibu || 'Nama Ibu' }}
|
{{ form.nama_bapak || 'Nama Ayah' }} & {{ form.nama_ibu || 'Nama Ibu' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -89,4 +87,20 @@ const getFullPhotoUrl = (photo) => {
|
|||||||
.bg-pattern {
|
.bg-pattern {
|
||||||
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="islamic" x="0" y="0" width="25" height="25" patternUnits="userSpaceOnUse"><g fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"><path d="M12.5 0 L25 12.5 L12.5 25 L0 12.5 Z M6.25 6.25 L18.75 6.25 L18.75 18.75 L6.25 18.75 Z"/><circle cx="12.5" cy="12.5" r="3"/></g></pattern></defs><rect width="100%" height="100%" fill="url(%23islamic)"/></svg>');
|
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="islamic" x="0" y="0" width="25" height="25" patternUnits="userSpaceOnUse"><g fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"><path d="M12.5 0 L25 12.5 L12.5 25 L0 12.5 Z M6.25 6.25 L18.75 6.25 L18.75 18.75 L6.25 18.75 Z"/><circle cx="12.5" cy="12.5" r="3"/></g></pattern></defs><rect width="100%" height="100%" fill="url(%23islamic)"/></svg>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Efek animasi halus muncul dari atas */
|
||||||
|
@keyframes fade-in-down {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in-down {
|
||||||
|
animation: fade-in-down 1s ease-out;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,33 +1,55 @@
|
|||||||
```vue
|
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-hidden">
|
<div
|
||||||
<!-- Background Pattern -->
|
class="min-h-screen w-full relative bg-gradient-to-br from-blue-900 via-blue-800 to-blue-900 overflow-hidden"
|
||||||
|
>
|
||||||
|
<!-- 🌙 Background Pattern -->
|
||||||
<div class="absolute inset-0 bg-pattern opacity-20"></div>
|
<div class="absolute inset-0 bg-pattern opacity-20"></div>
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Kubah Decorations -->
|
||||||
|
<div class="absolute top-0 left-8 md:left-32 w-16 md:w-34 kubah-swing animation-delay-300">
|
||||||
|
<img src="/kubah.png" alt="Kubah" class="w-full h-auto opacity-80" />
|
||||||
|
</div>
|
||||||
|
<div class="absolute top-0 right-8 md:right-22 w-16 md:w-44 kubah-swing animation-delay-600">
|
||||||
|
<img src="/kubah.png" alt="Kubah" class="w-full h-auto opacity-80" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 🌸 Main Content -->
|
||||||
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-12">
|
<div class="relative z-10 min-h-screen flex items-center justify-center px-4 md:px-8 py-12">
|
||||||
<div class="text-center max-w-4xl mx-auto">
|
<div class="text-center max-w-4xl mx-auto">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="mb-10 animate-fade-in-down">
|
<div class="mb-10 animate-fade-in-down">
|
||||||
<h1 class="text-yellow-400 text-3xl md:text-5xl lg:text-6xl font-bold mb-4 md:mb-6 font-script">
|
<h1
|
||||||
|
class="text-yellow-400 text-3xl md:text-5xl lg:text-6xl font-bold mb-4 md:mb-6 font-script"
|
||||||
|
>
|
||||||
Terima Kasih
|
Terima Kasih
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-white text-sm md:text-base lg:text-lg leading-relaxed max-w-3xl mx-auto">
|
<p
|
||||||
|
class="text-white text-sm md:text-base lg:text-lg leading-relaxed max-w-3xl mx-auto"
|
||||||
|
>
|
||||||
Kami mengucapkan terima kasih atas kehadiran serta doa restu yang diberikan untuk
|
Kami mengucapkan terima kasih atas kehadiran serta doa restu yang diberikan untuk
|
||||||
<span class="text-yellow-400 font-semibold">{{ jsonData.nama_panggilan || 'putra kami' }}</span>.
|
<span class="text-yellow-400 font-semibold">{{
|
||||||
|
jsonData.nama_panggilan || "putra kami"
|
||||||
|
}}</span>.
|
||||||
Semoga Allah SWT senantiasa melimpahkan rahmat dan keberkahan kepada kita semua.
|
Semoga Allah SWT senantiasa melimpahkan rahmat dan keberkahan kepada kita semua.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Family Info -->
|
<!-- Family Info -->
|
||||||
<div class="mb-12 animate-fade-in-up animation-delay-300">
|
<div class="mb-12 animate-fade-in-up animation-delay-300">
|
||||||
<h2 class="text-yellow-400 text-xl md:text-2xl lg:text-3xl font-bold mb-6 md:mb-8">
|
<h2
|
||||||
|
class="text-yellow-400 text-xl md:text-2xl lg:text-3xl font-bold mb-6 md:mb-8"
|
||||||
|
>
|
||||||
Kami Keluarga Besar Dari
|
Kami Keluarga Besar Dari
|
||||||
</h2>
|
</h2>
|
||||||
<div class="space-y-4 md:space-y-6">
|
<div class="space-y-4 md:space-y-6">
|
||||||
<div class="bg-white/10 backdrop-blur-md rounded-2xl p-4 md:p-6 border border-yellow-400/30 shadow-lg animate-fade-in-up animation-delay-500">
|
<div
|
||||||
<div class="text-yellow-400 text-base md:text-lg font-semibold mb-2">
|
class="bg-white/10 backdrop-blur-md rounded-2xl p-4 md:p-6 border border-yellow-400/30 shadow-lg animate-fade-in-up animation-delay-500"
|
||||||
{{ jsonData.nama_bapak || 'Bpk H. Munawar Huda, S.H.' }} & {{ jsonData.nama_ibu || 'Ibu Hj. Dinah, A.M.Keb' }}
|
>
|
||||||
|
<div
|
||||||
|
class="text-yellow-400 text-base md:text-lg font-semibold mb-2"
|
||||||
|
>
|
||||||
|
{{ jsonData.nama_bapak || "Bpk H. Munawar Huda, S.H." }} &
|
||||||
|
{{ jsonData.nama_ibu || "Ibu Hj. Dinah, A.M.Keb" }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,91 +57,147 @@
|
|||||||
|
|
||||||
<!-- Final Message -->
|
<!-- Final Message -->
|
||||||
<div class="animate-fade-in-up animation-delay-1200">
|
<div class="animate-fade-in-up animation-delay-1200">
|
||||||
<div class="bg-gradient-to-r from-yellow-400/20 to-yellow-600/20 backdrop-blur-md rounded-2xl p-6 md:p-8 border border-yellow-400/50 shadow-lg">
|
<div
|
||||||
|
class="bg-gradient-to-r from-yellow-400/20 to-yellow-600/20 backdrop-blur-md rounded-2xl p-6 md:p-8 border border-yellow-400/50 shadow-lg"
|
||||||
|
>
|
||||||
<p class="text-white text-base md:text-lg font-medium mb-4 italic">
|
<p class="text-white text-base md:text-lg font-medium mb-4 italic">
|
||||||
"Dan Allah telah mengeluarkan kamu dari perut ibumu dalam keadaan tidak mengetahui sesuatupun..."
|
"Dan Allah telah mengeluarkan kamu dari perut ibumu dalam keadaan
|
||||||
|
tidak mengetahui sesuatupun..."
|
||||||
|
</p>
|
||||||
|
<p class="text-yellow-400 text-sm md:text-base font-semibold">
|
||||||
|
- QS. An-Nahl: 78
|
||||||
</p>
|
</p>
|
||||||
<p class="text-yellow-400 text-sm md:text-base font-semibold">- QS. An-Nahl: 78</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Social Media Links -->
|
<!-- Social Media Links -->
|
||||||
<div class="mt-10 md:mt-12 animate-fade-in-up animation-delay-1500 flex justify-center space-x-4 md:space-x-6">
|
<!-- Social Media Links -->
|
||||||
<a
|
<div
|
||||||
v-if="jsonData.link_instagram"
|
class="mt-10 md:mt-12 animate-fade-in-up animation-delay-1500 flex justify-center space-x-4 md:space-x-6"
|
||||||
:href="jsonData.link_instagram"
|
>
|
||||||
target="_blank"
|
<a
|
||||||
rel="noopener noreferrer"
|
v-if="jsonData.link_instagram"
|
||||||
class="rounded-full p-2 md:p-3 backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
:href="jsonData.link_instagram"
|
||||||
aria-label="Instagram"
|
target="_blank"
|
||||||
>
|
rel="noopener noreferrer"
|
||||||
<Icon name="lucide:instagram" class="w-5 h-5 md:w-6 md:h-6 text-yellow-400" />
|
class="w-10 h-10 md:w-12 md:h-12 flex items-center justify-center rounded-full backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
||||||
</a>
|
aria-label="Instagram"
|
||||||
<a
|
>
|
||||||
v-if="jsonData.link_facebook"
|
<Icon
|
||||||
:href="jsonData.link_facebook"
|
name="lucide:instagram"
|
||||||
target="_blank"
|
class="w-5 h-5 md:w-6 md:h-6 text-yellow-400"
|
||||||
rel="noopener noreferrer"
|
/>
|
||||||
class="rounded-full p-2 md:p-3 backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
</a>
|
||||||
aria-label="Facebook"
|
|
||||||
>
|
<a
|
||||||
<Icon name="lucide:facebook" class="w-5 h-5 md:w-6 md:h-6 text-yellow-400" />
|
v-if="jsonData.link_facebook"
|
||||||
</a>
|
:href="jsonData.link_facebook"
|
||||||
<a
|
target="_blank"
|
||||||
v-if="jsonData.link_twitter"
|
rel="noopener noreferrer"
|
||||||
:href="jsonData.link_twitter"
|
class="w-10 h-10 md:w-12 md:h-12 flex items-center justify-center rounded-full backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
||||||
target="_blank"
|
aria-label="Facebook"
|
||||||
rel="noopener noreferrer"
|
>
|
||||||
class="rounded-full p-2 md:p-3 backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
<Icon
|
||||||
aria-label="Twitter"
|
name="lucide:facebook"
|
||||||
>
|
class="w-5 h-5 md:w-6 md:h-6 text-yellow-400"
|
||||||
<Icon name="lucide:twitter" class="w-5 h-5 md:w-6 md:h-6 text-yellow-400" />
|
/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
|
||||||
|
<a
|
||||||
|
v-if="jsonData.link_twitter"
|
||||||
|
:href="jsonData.link_twitter"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="w-10 h-10 md:w-12 md:h-12 flex items-center justify-center rounded-full backdrop-blur-md border border-yellow-400/30 hover:border-yellow-400/60 hover:bg-white/20 transition-all duration-300 transform hover:scale-110"
|
||||||
|
aria-label="Twitter"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name="lucide:twitter"
|
||||||
|
class="w-5 h-5 md:w-6 md:h-6 text-yellow-400"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Copyright -->
|
<!-- Footer -->
|
||||||
<div class="absolute bottom-4 left-1/2 transform -translate-x-1/2 z-10">
|
<div class="absolute bottom-4 left-1/2 transform -translate-x-1/2 z-10">
|
||||||
<p class="text-white/60 text-xs text-center">© {{ currentYear }} - Invitation Template</p>
|
<p class="text-white/60 text-xs text-center">
|
||||||
|
© {{ currentYear }} - Invitation Template
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
childName: {
|
childName: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: "",
|
||||||
},
|
},
|
||||||
jsonData: {
|
jsonData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({}),
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const currentYear = computed(() => new Date().getFullYear())
|
const currentYear = computed(() => new Date().getFullYear());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* Animations & bg-pattern */
|
/* =========================
|
||||||
|
🎨 Background Pattern
|
||||||
|
========================= */
|
||||||
.bg-pattern {
|
.bg-pattern {
|
||||||
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><pattern id='pattern' x='0' y='0' width='20' height='20' patternUnits='userSpaceOnUse'><path d='M10 5 L15 10 L10 15 L5 10 Z' fill='none' stroke='rgba(255,255,255,0.1)' stroke-width='0.5'/></pattern></defs><rect width='100' height='100' fill='url(%23pattern)'/></svg>");
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><pattern id='pattern' x='0' y='0' width='20' height='20' patternUnits='userSpaceOnUse'><path d='M10 5 L15 10 L10 15 L5 10 Z' fill='none' stroke='rgba(255,255,255,0.1)' stroke-width='0.5'/></pattern></defs><rect width='100' height='100' fill='url(%23pattern)'/></svg>");
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-fade-in-up {
|
/* =========================
|
||||||
animation: fadeInUp 1s ease-out forwards;
|
✨ General Animations
|
||||||
|
========================= */
|
||||||
|
.animate-sway {
|
||||||
|
animation: sway 3s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes sway {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
🕌 Smooth Kubah Swing
|
||||||
|
========================= */
|
||||||
|
.kubah-swing {
|
||||||
|
animation: kubahSwingSmooth 6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
|
||||||
|
transform-origin: top center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes kubahSwingSmooth {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
20% { transform: rotate(2.5deg); }
|
||||||
|
40% { transform: rotate(-2.5deg); }
|
||||||
|
60% { transform: rotate(2deg); }
|
||||||
|
80% { transform: rotate(-2deg); }
|
||||||
|
100% { transform: rotate(0deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
✨ Fade Animations
|
||||||
|
========================= */
|
||||||
.animate-fade-in-down {
|
.animate-fade-in-down {
|
||||||
animation: fadeInDown 1s ease-out forwards;
|
animation: fadeInDown 1s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
.animate-fade-in-up {
|
||||||
@keyframes fadeInUp {
|
animation: fadeInUp 1s ease-out forwards;
|
||||||
from { opacity: 0; transform: translateY(20px); }
|
}
|
||||||
to { opacity: 1; transform: translateY(0); }
|
.animate-fade-in-left {
|
||||||
|
animation: fadeInLeft 1s ease-out forwards;
|
||||||
|
}
|
||||||
|
.animate-fade-in-right {
|
||||||
|
animation: fadeInRight 1s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeInDown {
|
@keyframes fadeInDown {
|
||||||
@ -127,20 +205,32 @@ const currentYear = computed(() => new Date().getFullYear())
|
|||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.animation-delay-300 {
|
@keyframes fadeInUp {
|
||||||
animation-delay: 0.3s;
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.animation-delay-500 {
|
@keyframes fadeInLeft {
|
||||||
animation-delay: 0.5s;
|
from { opacity: 0; transform: translateX(-20px); }
|
||||||
|
to { opacity: 1; transform: translateX(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.animation-delay-1200 {
|
@keyframes fadeInRight {
|
||||||
animation-delay: 1.2s;
|
from { opacity: 0; transform: translateX(20px); }
|
||||||
|
to { opacity: 1; transform: translateX(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.animation-delay-1500 {
|
/* =========================
|
||||||
animation-delay: 1.5s;
|
⏱️ Delay Utilities
|
||||||
|
========================= */
|
||||||
|
.animation-delay-300 { animation-delay: 0.3s; }
|
||||||
|
.animation-delay-600 { animation-delay: 0.6s; }
|
||||||
|
.animation-delay-1000 { animation-delay: 1s; }
|
||||||
|
|
||||||
|
/* =========================
|
||||||
|
🕌 Font Arabic
|
||||||
|
========================= */
|
||||||
|
.arabic-text {
|
||||||
|
font-family: 'Noto Naskh Arabic', serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
```
|
|
||||||
@ -31,7 +31,6 @@
|
|||||||
<main
|
<main
|
||||||
class="relative z-10 min-h-screen flex items-center justify-center p-4 transition-all duration-700 ease-in-out"
|
class="relative z-10 min-h-screen flex items-center justify-center p-4 transition-all duration-700 ease-in-out"
|
||||||
>
|
>
|
||||||
<!-- Landing Page -->
|
|
||||||
<KhitanA
|
<KhitanA
|
||||||
v-if="currentSection === 'landing'"
|
v-if="currentSection === 'landing'"
|
||||||
:childName="formData.nama_panggilan"
|
:childName="formData.nama_panggilan"
|
||||||
@ -39,37 +38,30 @@
|
|||||||
@next-page="switchSection('introduction')"
|
@next-page="switchSection('introduction')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Introduction -->
|
<KhitanIntroduction
|
||||||
<KhitanIntroduction
|
|
||||||
v-if="currentSection === 'introduction'"
|
v-if="currentSection === 'introduction'"
|
||||||
:form="formData"
|
:form="formData"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<KhitanEvent
|
||||||
|
v-if="currentSection === 'event'"
|
||||||
|
:hari_tanggal_acara="formData.hari_tanggal_acara"
|
||||||
|
:waktu="formData.waktu"
|
||||||
|
:alamat="formData.alamat"
|
||||||
|
:link_gmaps="formData.link_gmaps"
|
||||||
|
:hitung_mundur_mulai="formData.hitung_mundur_mulai"
|
||||||
|
:hari_tanggal_syukuran="formData.hari_tanggal_syukuran"
|
||||||
|
:waktu_syukuran="formData.waktu_syukuran"
|
||||||
|
:alamat_syukuran="formData.alamat_syukuran"
|
||||||
|
:link_gmaps_syukuran="formData.link_gmaps_syukuran"
|
||||||
|
:hitung_mundur_selesai="formData.hitung_mundur_selesai"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Event -->
|
|
||||||
<KhitanEvent
|
|
||||||
v-if="currentSection === 'event'"
|
|
||||||
:hari_tanggal_acara="formData.hari_tanggal_acara"
|
|
||||||
:waktu="formData.waktu"
|
|
||||||
:alamat="formData.alamat"
|
|
||||||
:link_gmaps="formData.link_gmaps"
|
|
||||||
:hitung_mundur_mulai="formData.hitung_mundur_mulai"
|
|
||||||
|
|
||||||
:hari_tanggal_syukuran="formData.hari_tanggal_syukuran"
|
|
||||||
:waktu_syukuran="formData.waktu_syukuran"
|
|
||||||
:alamat_syukuran="formData.alamat_syukuran"
|
|
||||||
:link_gmaps_syukuran="formData.link_gmaps_syukuran"
|
|
||||||
:hitung_mundur_selesai="formData.hitung_mundur_selesai"
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Gallery -->
|
|
||||||
<KhitanGallery
|
<KhitanGallery
|
||||||
v-if="currentSection === 'gallery'"
|
v-if="currentSection === 'gallery'"
|
||||||
:images="galleryImages"
|
:images="galleryImages"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Guest Book -->
|
|
||||||
<KhitanSay
|
<KhitanSay
|
||||||
v-if="currentSection === 'say'"
|
v-if="currentSection === 'say'"
|
||||||
:guestName="data.nama_tamu"
|
:guestName="data.nama_tamu"
|
||||||
@ -77,18 +69,18 @@
|
|||||||
@addMessage="addMessage"
|
@addMessage="addMessage"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<KhitanThankYou
|
||||||
<!-- Thank You -->
|
v-if="currentSection === 'thanks'"
|
||||||
<KhitanThankYou v-if="currentSection === 'thanks'" :childName="formData.nama_panggilan" :jsonData="formData" />
|
:childName="formData.nama_panggilan"
|
||||||
|
:jsonData="formData"
|
||||||
|
/>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useRuntimeConfig } from '#app'
|
import { useRuntimeConfig } from '#app'
|
||||||
|
|
||||||
// ================== IMPORT KOMPONEN ==================
|
|
||||||
import KhitanA from '~/components/templates/khitan/KhitanA.vue'
|
import KhitanA from '~/components/templates/khitan/KhitanA.vue'
|
||||||
import KhitanIntroduction from '~/components/templates/khitan/Introduction.vue'
|
import KhitanIntroduction from '~/components/templates/khitan/Introduction.vue'
|
||||||
import KhitanEvent from '~/components/templates/khitan/Event.vue'
|
import KhitanEvent from '~/components/templates/khitan/Event.vue'
|
||||||
@ -96,48 +88,30 @@ import KhitanGallery from '~/components/templates/khitan/Gallery.vue'
|
|||||||
import KhitanSay from '~/components/templates/khitan/GuestBook.vue'
|
import KhitanSay from '~/components/templates/khitan/GuestBook.vue'
|
||||||
import KhitanThankYou from '~/components/templates/khitan/ThankYou.vue'
|
import KhitanThankYou from '~/components/templates/khitan/ThankYou.vue'
|
||||||
|
|
||||||
// ================== PROPS ==================
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: { type: Object, required: true }
|
data: { type: Object, required: true }
|
||||||
})
|
})
|
||||||
|
|
||||||
// ================== BACKEND CONFIG ==================
|
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const backendUrl = config.public.apiBaseUrl
|
const backendUrl = config.public.apiBaseUrl
|
||||||
|
|
||||||
// ================== FORM DATA ==================
|
|
||||||
const formData = computed(() => props.data.form || {})
|
const formData = computed(() => props.data.form || {})
|
||||||
|
|
||||||
// ================== GALERI ==================
|
|
||||||
const galleryImages = computed(() => {
|
const galleryImages = computed(() => {
|
||||||
const f = formData.value.foto
|
const f = formData.value.foto
|
||||||
|
if (Array.isArray(f)) {
|
||||||
|
return f.map(img => `${backendUrl}/storage/${img}`)
|
||||||
if (Array.isArray(f)) {
|
}
|
||||||
return f.map(img => `${backendUrl}/storage/${img}`)
|
return [
|
||||||
}
|
formData.value.foto_1,
|
||||||
|
formData.value.foto_2,
|
||||||
// Jika masih bentuk lama (foto_1, foto_2, dst.)
|
formData.value.foto_3,
|
||||||
return [
|
formData.value.foto_4,
|
||||||
formData.value.foto_1,
|
formData.value.foto_5
|
||||||
formData.value.foto_2,
|
].filter(Boolean).map(img => `${backendUrl}/${img}`)
|
||||||
formData.value.foto_3,
|
|
||||||
formData.value.foto_4,
|
|
||||||
formData.value.foto_5
|
|
||||||
].filter(Boolean).map(img => `${backendUrl}/${img}`)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Foto utama diambil dari foto pertama
|
|
||||||
const mainPhoto = computed(() => {
|
|
||||||
const firstPhoto = formData.value.foto?.[0]
|
|
||||||
return firstPhoto ? `${backendUrl}/${firstPhoto}` : ''
|
|
||||||
})
|
|
||||||
|
|
||||||
// ================== NAVIGASI SECTION ==================
|
|
||||||
const currentSection = ref('landing')
|
const currentSection = ref('landing')
|
||||||
const switchSection = (s) => (currentSection.value = s)
|
const switchSection = (s) => (currentSection.value = s)
|
||||||
|
|
||||||
// ================== MUSIK ==================
|
|
||||||
const audioPlayer = ref(null)
|
const audioPlayer = ref(null)
|
||||||
const isPlaying = ref(false)
|
const isPlaying = ref(false)
|
||||||
const musicUrl = computed(() =>
|
const musicUrl = computed(() =>
|
||||||
@ -154,11 +128,9 @@ const toggleMusic = () => {
|
|||||||
isPlaying.value = !isPlaying.value
|
isPlaying.value = !isPlaying.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================== GUEST BOOK ==================
|
|
||||||
const messages = ref([])
|
const messages = ref([])
|
||||||
const addMessage = (msg) => messages.value.push(msg)
|
const addMessage = (msg) => messages.value.push(msg)
|
||||||
|
|
||||||
// ================== STYLE NAV ==================
|
|
||||||
const navClass = (s) =>
|
const navClass = (s) =>
|
||||||
currentSection.value === s
|
currentSection.value === s
|
||||||
? 'text-blue-800 underline'
|
? 'text-blue-800 underline'
|
||||||
@ -166,6 +138,31 @@ const navClass = (s) =>
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
/* Pastikan benar-benar fullscreen */
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
:host,
|
||||||
|
div[min-h-screen],
|
||||||
|
.min-h-screen {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hilangkan white space akibat scroll */
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pastikan gradient menutup seluruh layar */
|
||||||
|
div[min-h-screen] {
|
||||||
|
position: relative;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transisi section tetap */
|
||||||
main {
|
main {
|
||||||
transition: all 0.7s ease-in-out;
|
transition: all 0.7s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
proyek-frontend/public/kubah.png
Normal file
BIN
proyek-frontend/public/kubah.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
BIN
proyek-frontend/public/nickname.png
Normal file
BIN
proyek-frontend/public/nickname.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Loading…
Reference in New Issue
Block a user