all page is done
This commit is contained in:
155
app/[locale]/about/noteFlans/page.tsx
Normal file
155
app/[locale]/about/noteFlans/page.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { FileText, ChevronRight } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Statistics } from "@/components/pages/home";
|
||||
|
||||
const ease = [0.22, 1, 0.36, 1] as [number, number, number, number];
|
||||
|
||||
export default function NoteFlansPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Statistics />
|
||||
<main className="min-h-screen bg-[#0f0e0d] text-white">
|
||||
{/* ── Hero ── */}
|
||||
<section className="relative w-full h-120 md:h-145 overflow-hidden">
|
||||
<Image
|
||||
src="/images/about/pp.avif"
|
||||
alt={t("about.noteFlansPage.hero.title")}
|
||||
fill
|
||||
className="object-cover"
|
||||
priority
|
||||
/>
|
||||
|
||||
{/* Layered overlays */}
|
||||
<div className="absolute inset-0 bg-black/45" />
|
||||
<div className="absolute inset-0 bg-linear-to-b from-transparent via-black/20 to-[#0f0e0d]" />
|
||||
|
||||
{/* Grain texture */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-20 mix-blend-overlay pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Content anchored bottom-left */}
|
||||
<div className="relative z-10 flex flex-col justify-end h-full max-w-6xl mx-auto px-6 pb-16 md:pb-20">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.22em] text-red-600 mb-4"
|
||||
>
|
||||
{t("about.noteFlansPage.hero.eyebrow")}
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.65, ease, delay: 0.08 }}
|
||||
className="text-5xl md:text-7xl font-black uppercase leading-[0.92] tracking-tight text-white"
|
||||
>
|
||||
{t("about.noteFlansPage.hero.titleLine1")}
|
||||
<br />
|
||||
<span className="text-red-600">
|
||||
{t("about.noteFlansPage.hero.titleLine2")}
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.2 }}
|
||||
className="mt-5 max-w-xl text-sm md:text-base text-gray-300 leading-relaxed"
|
||||
>
|
||||
{t("about.noteFlansPage.hero.description")}
|
||||
</motion.p>
|
||||
|
||||
{/* Animated underline */}
|
||||
<motion.div
|
||||
initial={{ scaleX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={{ delay: 0.35, duration: 0.8, ease }}
|
||||
style={{ originX: 0 }}
|
||||
className="mt-8 w-20 h-px bg-red-600"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Content section ── */}
|
||||
<section className="max-w-6xl mx-auto px-6 py-20">
|
||||
{/* Section label */}
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.2em] text-red-600 mb-10"
|
||||
>
|
||||
{t("about.noteFlansPage.section.label")}
|
||||
</motion.p>
|
||||
|
||||
{/* Two-column layout: description left, details right */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-20 items-start">
|
||||
{/* Left: main description */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div className="mt-8 flex items-center gap-2 text-red-600 text-sm font-bold cursor-pointer group w-fit">
|
||||
<span>{t("about.noteFlansPage.section.cta")}</span>
|
||||
<ChevronRight
|
||||
size={16}
|
||||
className="group-hover:translate-x-1 transition-transform duration-200"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right: feature list */}
|
||||
<motion.ul
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="flex flex-col divide-y divide-white/5"
|
||||
>
|
||||
{(t.raw("about.noteFlansPage.section.features") as string[]).map(
|
||||
(feature: string, i: number) => (
|
||||
<li key={i} className="flex items-start gap-3 py-4 group">
|
||||
<div className="mt-0.5 w-6 h-6 rounded-lg bg-red-600/10 border border-red-600/20 flex items-center justify-center shrink-0 group-hover:bg-red-600/20 transition-colors duration-200">
|
||||
<FileText size={12} className="text-red-600" />
|
||||
</div>
|
||||
<span className="text-sm text-gray-400 leading-relaxed group-hover:text-gray-200 transition-colors duration-200">
|
||||
{feature}
|
||||
</span>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</motion.ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Bottom strip ── */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-6xl mx-auto px-6 pb-20 border-t border-white/5 pt-10 flex items-center justify-between"
|
||||
>
|
||||
<p className="text-sm text-gray-600 uppercase tracking-widest font-bold">
|
||||
{t("about.noteFlansPage.footer.label")}
|
||||
</p>
|
||||
<div className="w-8 h-px bg-red-600/40" />
|
||||
</motion.div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
147
app/[locale]/about/notePP/page.tsx
Normal file
147
app/[locale]/about/notePP/page.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { FileText, ChevronRight } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Statistics } from "@/components/pages/home";
|
||||
|
||||
const ease = [0.22, 1, 0.36, 1] as [number, number, number, number];
|
||||
|
||||
export default function NotePPPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Statistics />
|
||||
<main className="min-h-screen bg-[#0f0e0d] text-white">
|
||||
{/* Hero Section */}
|
||||
<section className="relative w-full h-120 md:h-145 overflow-hidden">
|
||||
<Image
|
||||
src="/images/about/pp.avif"
|
||||
alt={t("about.notePPPage.hero.title")}
|
||||
fill
|
||||
className="object-cover"
|
||||
priority
|
||||
/>
|
||||
|
||||
<div className="absolute inset-0 bg-black/45" />
|
||||
<div className="absolute inset-0 bg-linear-to-b from-transparent via-black/20 to-[#0f0e0d]" />
|
||||
|
||||
<div
|
||||
className="absolute inset-0 opacity-20 mix-blend-overlay pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="relative z-10 flex flex-col justify-end h-full max-w-6xl mx-auto px-6 pb-16 md:pb-20">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.22em] text-red-600 mb-4"
|
||||
>
|
||||
{t("about.notePPPage.hero.eyebrow")}
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.65, ease, delay: 0.08 }}
|
||||
className="text-5xl md:text-7xl font-black uppercase leading-[0.92] tracking-tight text-white"
|
||||
>
|
||||
{t("about.notePPPage.hero.titleLine1")}
|
||||
<br />
|
||||
<span className="text-red-600">
|
||||
{t("about.notePPPage.hero.titleLine2")}
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.2 }}
|
||||
className="mt-5 max-w-xl text-sm md:text-base text-gray-300 leading-relaxed"
|
||||
>
|
||||
{t("about.notePPPage.hero.description")}
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
initial={{ scaleX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={{ delay: 0.35, duration: 0.8, ease }}
|
||||
style={{ originX: 0 }}
|
||||
className="mt-8 w-20 h-px bg-red-600"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Content Section */}
|
||||
<section className="max-w-6xl mx-auto px-6 py-20">
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.2em] text-red-600 mb-10"
|
||||
>
|
||||
{t("about.notePPPage.section.label")}
|
||||
</motion.p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-20 items-start">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div className="mt-8 flex items-center gap-2 text-red-600 text-sm font-bold cursor-pointer group w-fit">
|
||||
<span>{t("about.notePPPage.section.cta")}</span>
|
||||
<ChevronRight
|
||||
size={16}
|
||||
className="group-hover:translate-x-1 transition-transform duration-200"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.ul
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="flex flex-col divide-y divide-white/5"
|
||||
>
|
||||
{(t.raw("about.notePPPage.section.features") as string[]).map(
|
||||
(feature: string, i: number) => (
|
||||
<li key={i} className="flex items-start gap-3 py-4 group">
|
||||
<div className="mt-0.5 w-6 h-6 rounded-lg bg-red-600/10 border border-red-600/20 flex items-center justify-center shrink-0 group-hover:bg-red-600/20 transition-colors duration-200">
|
||||
<FileText size={12} className="text-red-600" />
|
||||
</div>
|
||||
<span className="text-sm text-gray-400 leading-relaxed group-hover:text-gray-200 transition-colors duration-200">
|
||||
{feature}
|
||||
</span>
|
||||
</li>
|
||||
),
|
||||
)}
|
||||
</motion.ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Bottom strip */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-6xl mx-auto px-6 pb-20 border-t border-white/5 pt-10 flex items-center justify-between"
|
||||
>
|
||||
<p className="text-sm text-gray-600 uppercase tracking-widest font-bold">
|
||||
{t("about.notePPPage.footer.label")}
|
||||
</p>
|
||||
<div className="w-8 h-px bg-red-600/40" />
|
||||
</motion.div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
147
app/[locale]/about/noteTrailer/page.tsx
Normal file
147
app/[locale]/about/noteTrailer/page.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import { FileText, ChevronRight } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Statistics } from "@/components/pages/home";
|
||||
|
||||
const ease = [0.22, 1, 0.36, 1] as [number, number, number, number];
|
||||
|
||||
export default function NoteTrailerPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Statistics />
|
||||
<main className="min-h-screen bg-[#0f0e0d] text-white">
|
||||
{/* Hero Section */}
|
||||
<section className="relative w-full h-120 md:h-145 overflow-hidden">
|
||||
<Image
|
||||
src="/images/about/pp.avif"
|
||||
alt={t("about.noteTrailerPage.hero.title")}
|
||||
fill
|
||||
className="object-cover"
|
||||
priority
|
||||
/>
|
||||
|
||||
<div className="absolute inset-0 bg-black/45" />
|
||||
<div className="absolute inset-0 bg-linear-to-b from-transparent via-black/20 to-[#0f0e0d]" />
|
||||
|
||||
<div
|
||||
className="absolute inset-0 opacity-20 mix-blend-overlay pointer-events-none"
|
||||
style={{
|
||||
backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="relative z-10 flex flex-col justify-end h-full max-w-6xl mx-auto px-6 pb-16 md:pb-20">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.22em] text-red-600 mb-4"
|
||||
>
|
||||
{t("about.noteTrailerPage.hero.eyebrow")}
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.65, ease, delay: 0.08 }}
|
||||
className="text-5xl md:text-7xl font-black uppercase leading-[0.92] tracking-tight text-white"
|
||||
>
|
||||
{t("about.noteTrailerPage.hero.titleLine1")}
|
||||
<br />
|
||||
<span className="text-red-600">
|
||||
{t("about.noteTrailerPage.hero.titleLine2")}
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.2 }}
|
||||
className="mt-5 max-w-xl text-sm md:text-base text-gray-300 leading-relaxed"
|
||||
>
|
||||
{t("about.noteTrailerPage.hero.description")}
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
initial={{ scaleX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={{ delay: 0.35, duration: 0.8, ease }}
|
||||
style={{ originX: 0 }}
|
||||
className="mt-8 w-20 h-px bg-red-600"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Content Section */}
|
||||
<section className="max-w-6xl mx-auto px-6 py-20">
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.2em] text-red-600 mb-10"
|
||||
>
|
||||
{t("about.noteTrailerPage.section.label")}
|
||||
</motion.p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-20 items-start">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div className="mt-8 flex items-center gap-2 text-red-600 text-sm font-bold cursor-pointer group w-fit">
|
||||
<span>{t("about.noteTrailerPage.section.cta")}</span>
|
||||
<ChevronRight
|
||||
size={16}
|
||||
className="group-hover:translate-x-1 transition-transform duration-200"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
<motion.ul
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease, delay: 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="flex flex-col divide-y divide-white/5"
|
||||
>
|
||||
{(
|
||||
t.raw("about.noteTrailerPage.section.features") as string[]
|
||||
).map((feature: string, i: number) => (
|
||||
<li key={i} className="flex items-start gap-3 py-4 group">
|
||||
<div className="mt-0.5 w-6 h-6 rounded-lg bg-red-600/10 border border-red-600/20 flex items-center justify-center shrink-0 group-hover:bg-red-600/20 transition-colors duration-200">
|
||||
<FileText size={12} className="text-red-600" />
|
||||
</div>
|
||||
<span className="text-sm text-gray-400 leading-relaxed group-hover:text-gray-200 transition-colors duration-200">
|
||||
{feature}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</motion.ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Bottom strip */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-6xl mx-auto px-6 pb-20 border-t border-white/5 pt-10 flex items-center justify-between"
|
||||
>
|
||||
<p className="text-sm text-gray-600 uppercase tracking-widest font-bold">
|
||||
{t("about.noteTrailerPage.footer.label")}
|
||||
</p>
|
||||
<div className="w-8 h-px bg-red-600/40" />
|
||||
</motion.div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
182
app/[locale]/about/sertificate/page.tsx
Normal file
182
app/[locale]/about/sertificate/page.tsx
Normal file
@@ -0,0 +1,182 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
import { Download, ExternalLink, Award } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Statistics } from "@/components/pages/home";
|
||||
|
||||
export default function SertificatePage() {
|
||||
const t = useTranslations();
|
||||
|
||||
const certs = [
|
||||
{
|
||||
id: 1,
|
||||
src: "/images/about/sertificate.webp",
|
||||
title: "Sertifikat 1",
|
||||
desc: "lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
||||
year: "2024",
|
||||
},
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<Statistics />
|
||||
<main className="min-h-screen bg-[#0f0e0d] text-white pb-44 overflow-x-hidden">
|
||||
{/* ── Hero ── */}
|
||||
<section className="max-w-6xl mx-auto px-6 pt-14 pb-10">
|
||||
<motion.span
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="text-[11px] font-black uppercase tracking-[0.22em] text-red-600"
|
||||
>
|
||||
{t("about.certificatePage.hero.label")}
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 24 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={
|
||||
{
|
||||
duration: 0.6,
|
||||
delay: 0.05,
|
||||
} as any
|
||||
}
|
||||
className="mt-3 text-5xl md:text-7xl font-black uppercase tracking-tight leading-[0.92]"
|
||||
>
|
||||
{t("about.certificatePage.hero.title1")}{" "}
|
||||
<span className="text-red-600">
|
||||
{t("about.certificatePage.hero.title2")}
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={
|
||||
{
|
||||
duration: 0.6,
|
||||
delay: 0.15,
|
||||
} as any
|
||||
}
|
||||
className="mt-5 max-w-lg text-sm md:text-base text-gray-300 leading-relaxed"
|
||||
>
|
||||
{t("about.certificatePage.hero.description")}
|
||||
</motion.p>
|
||||
|
||||
{/* Divider */}
|
||||
<motion.div
|
||||
initial={{ scaleX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={
|
||||
{
|
||||
delay: 0.3,
|
||||
duration: 0.7,
|
||||
} as any
|
||||
}
|
||||
style={{ originX: 0 }}
|
||||
className="mt-8 w-20 h-px bg-red-600"
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* ── Horizontal scroll track ── */}
|
||||
<section className="mt-4 max-w-6xl mx-auto">
|
||||
{/* Section header */}
|
||||
<div className=" px-6 flex items-center justify-between mb-6">
|
||||
<div className="flex items-center gap-2">
|
||||
<Award size={15} className="text-red-600" />
|
||||
<span className="text-xs font-black uppercase tracking-widest text-gray-300">
|
||||
{certs.length} {t("about.certificatePage.count.suffix")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Count strip ── */}
|
||||
<motion.section
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
className="max-w-6xl mx-auto px-6 my-5 flex items-center gap-6 border-y border-white/5 py-5"
|
||||
>
|
||||
<span className="text-6xl font-black text-white/10">
|
||||
{certs.length}
|
||||
</span>
|
||||
<p className="text-sm text-gray-300 leading-relaxed max-w-xs">
|
||||
{t("about.certificatePage.count.description")}
|
||||
</p>
|
||||
</motion.section>
|
||||
|
||||
{/* Scrollable row */}
|
||||
<div className="w-[80%] mx-auto flex gap-5 overflow-x-auto px-6 pb-6 scrollbar-none [-ms-overflow-style:none] [scrollbar-width:none] snap-x snap-mandatory">
|
||||
{certs.map((c, i) => (
|
||||
<motion.article
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.55, delay: i * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="group p-5 flex flex-row rounded-xl overflow-hidden bg-[#161514] border border-white/5 hover:border-red-600/25 transition-colors duration-300 w-full"
|
||||
>
|
||||
{/* ── Left: certificate image ── */}
|
||||
<div className="relative flex-none w-[50%] h-50 overflow-hidden">
|
||||
<Image
|
||||
src={c.src}
|
||||
alt={c.title}
|
||||
fill
|
||||
className="object-contain transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* ── Right: info + actions ── */}
|
||||
<div className="flex flex-col justify-between flex-1 px-5 py-5 gap-4 min-w-0">
|
||||
{/* Label + title + desc */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Award size={12} className="text-red-600 shrink-0" />
|
||||
<p className="text-[10px] font-black uppercase tracking-widest text-red-600">
|
||||
{t("about.certificatePage.card.badge")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h3 className="font-bold text-base md:text-lg text-white leading-tight">
|
||||
{c.title}
|
||||
</h3>
|
||||
|
||||
<p className="text-xs text-gray-300 leading-relaxed line-clamp-2">
|
||||
{c.desc}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Link
|
||||
href={c.src}
|
||||
target="_blank"
|
||||
className="flex items-center gap-1.5 h-8 px-4 rounded-xl bg-red-600 hover:bg-red-500 transition-colors duration-200 text-white text-xs font-bold"
|
||||
>
|
||||
<ExternalLink size={12} />
|
||||
{t("about.certificatePage.card.view")}
|
||||
</Link>
|
||||
|
||||
<a
|
||||
href={c.src}
|
||||
download
|
||||
className="flex items-center gap-1.5 h-8 px-4 rounded-xl border border-white/10 hover:border-red-600/40 hover:bg-red-600/5 transition-all duration-200 text-white/80 hover:text-red-600 text-xs font-bold"
|
||||
>
|
||||
<Download size={12} />
|
||||
{t("about.certificatePage.card.download")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</motion.article>
|
||||
))}
|
||||
|
||||
{/* End spacer */}
|
||||
<div className="flex-none w-2" />
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ export function InnerNavbar() {
|
||||
|
||||
const tabs = [
|
||||
{ name: t("about.subPages.baza"), value: "baza" },
|
||||
{ name: t("about.subPages.certificate"), value: "certificate" },
|
||||
{ name: t("about.subPages.certificate"), value: "sertificate" },
|
||||
{ name: t("about.subPages.notePP"), value: "notePP" },
|
||||
{ name: t("about.subPages.noteTrailer"), value: "noteTrailer" },
|
||||
{ name: t("about.subPages.noteFlans"), value: "noteFlans" },
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import DotAnimatsiya from "../../../dot/DotAnimatsiya";
|
||||
import Link from "next/link";
|
||||
import { BannerSlider } from "./slider";
|
||||
|
||||
export function Banner() {
|
||||
const t = useTranslations();
|
||||
const locale = useLocale();
|
||||
return (
|
||||
<section className="relative w-full lg:h-[86vh] h-screen min-h-150 overflow-hidden pt-20">
|
||||
<section className="relative w-full lg:h-[86vh] h-screen min-h-150 overflow-hidden min-[450px]:pt-10 pt-20">
|
||||
{/* Background Image */}
|
||||
<div
|
||||
className="absolute inset-0 z-0"
|
||||
|
||||
@@ -151,6 +151,95 @@
|
||||
}
|
||||
},
|
||||
"bottomText": "All works are carried out in accordance with state standards and safety requirements."
|
||||
},
|
||||
"certificatePage": {
|
||||
"hero": {
|
||||
"label": "Official Approvals",
|
||||
"title1": "Certifi",
|
||||
"title2": "cates",
|
||||
"description": "Official certificates and documents confirming the quality of our products and installation services."
|
||||
},
|
||||
"count": {
|
||||
"suffix": "certificates",
|
||||
"description": "Number of official certificates and approval documents obtained by our company during its operations."
|
||||
},
|
||||
"card": {
|
||||
"badge": "Official Document",
|
||||
"view": "View",
|
||||
"download": "Download"
|
||||
},
|
||||
"certificates": {
|
||||
"cert1": {
|
||||
"title": "Certificate 1",
|
||||
"desc": "Official certificate authorizing installation and supply of fire protection systems."
|
||||
}
|
||||
}
|
||||
},
|
||||
"notePPPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Technical Documentation",
|
||||
"titleLine1": "PP Pipes",
|
||||
"titleLine2": "& Fittings",
|
||||
"title": "Installation guide for PP pipes and fittings",
|
||||
"description": "Step-by-step instructions and best practices for properly installing polypropylene pipes and fittings to ensure reliable fire protection systems."
|
||||
},
|
||||
"section": {
|
||||
"label": "More Information",
|
||||
"cta": "View Document",
|
||||
"features": [
|
||||
"Use clean, debris-free pipes",
|
||||
"Ensure proper alignment before welding",
|
||||
"Apply recommended sealing techniques",
|
||||
"Test joints for leaks after installation"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "All technical details are for reference only."
|
||||
}
|
||||
},
|
||||
"noteTrailerPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Technical Documentation",
|
||||
"titleLine1": "Welded",
|
||||
"titleLine2": "Saddles",
|
||||
"title": "Installation guide for welded saddles",
|
||||
"description": "Detailed guidelines for safe placement and welding of saddles used in fire suppression systems, ensuring durable and leak-free connections."
|
||||
},
|
||||
"section": {
|
||||
"label": "More Information",
|
||||
"cta": "View Document",
|
||||
"features": [
|
||||
"Select correct saddle size",
|
||||
"Prepare surface for welding",
|
||||
"Follow manufacturer’s welding procedure",
|
||||
"Inspect welds for integrity"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "All technical details are for reference only."
|
||||
}
|
||||
},
|
||||
"noteFlansPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Technical Documentation",
|
||||
"titleLine1": "Nota",
|
||||
"titleLine2": "Flanslar",
|
||||
"title": "Installation guide for PP flanges",
|
||||
"description": "Comprehensive instructions for mounting polypropylene flanges, emphasizing correct sealing and connection procedures for a robust piping network."
|
||||
},
|
||||
"section": {
|
||||
"label": "More Information",
|
||||
"cta": "View Document",
|
||||
"features": [
|
||||
"Check pipe alignment before attaching flange",
|
||||
"Use proper gasket material",
|
||||
"Tighten bolts in cross pattern",
|
||||
"Verify seal integrity after assembly"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "All technical details are for reference only."
|
||||
}
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
|
||||
@@ -151,6 +151,95 @@
|
||||
}
|
||||
},
|
||||
"bottomText": "Все работы выполняются в соответствии с государственными стандартами и требованиями безопасности."
|
||||
},
|
||||
"certificatePage": {
|
||||
"hero": {
|
||||
"label": "Официальные подтверждения",
|
||||
"title1": "Сертифи",
|
||||
"title2": "каты",
|
||||
"description": "Официальные сертификаты и документы, подтверждающие качество нашей продукции и монтажных работ."
|
||||
},
|
||||
"count": {
|
||||
"suffix": "сертификатов",
|
||||
"description": "Количество официальных сертификатов и подтверждающих документов, полученных компанией за время деятельности."
|
||||
},
|
||||
"card": {
|
||||
"badge": "Официальный документ",
|
||||
"view": "Просмотреть",
|
||||
"download": "Скачать"
|
||||
},
|
||||
"certificates": {
|
||||
"cert1": {
|
||||
"title": "Сертификат 1",
|
||||
"desc": "Официальный сертификат, подтверждающий право на установку и поставку систем пожарной безопасности."
|
||||
}
|
||||
}
|
||||
},
|
||||
"notePPPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Техническая документация",
|
||||
"titleLine1": "ПП Трубы",
|
||||
"titleLine2": "и Фитинги",
|
||||
"title": "Инструкция по монтажу ПП труб и фитингов",
|
||||
"description": "Пошаговые инструкции и лучшие практики по правильной установке полипропиленовых труб и фитингов для обеспечения надежных систем пожаротушения."
|
||||
},
|
||||
"section": {
|
||||
"label": "Подробнее",
|
||||
"cta": "Просмотреть документ",
|
||||
"features": [
|
||||
"Используйте чистые трубы без мусора",
|
||||
"Обеспечьте правильное выравнивание перед сваркой",
|
||||
"Применяйте рекомендованные методы уплотнения",
|
||||
"Проверяйте соединения на утечки после установки"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Все технические детали приведены для справки."
|
||||
}
|
||||
},
|
||||
"noteTrailerPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Техническая документация",
|
||||
"titleLine1": "Вварные",
|
||||
"titleLine2": "Сёдла",
|
||||
"title": "Инструкция по монтажу вварных сёдел",
|
||||
"description": "Детальные указания по безопасному размещению и сварке седел, используемых в системах пожаротушения, для обеспечения прочных и герметичных соединений."
|
||||
},
|
||||
"section": {
|
||||
"label": "Подробнее",
|
||||
"cta": "Просмотреть документ",
|
||||
"features": [
|
||||
"Выберите правильный размер седла",
|
||||
"Подготовьте поверхность для сварки",
|
||||
"Следуйте процедуре сварки производителя",
|
||||
"Проверяйте целостность швов"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Все технические детали приведены для справки."
|
||||
}
|
||||
},
|
||||
"noteFlansPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Техническая документация",
|
||||
"titleLine1": "Nota",
|
||||
"titleLine2": "Flanslar",
|
||||
"title": "Инструкция по монтажу фланцев из ПП",
|
||||
"description": "Комплексные инструкции по установке полипропиленовых фланцев с акцентом на правильное уплотнение и процедуры соединения для надежной трубопроводной сети."
|
||||
},
|
||||
"section": {
|
||||
"label": "Подробнее",
|
||||
"cta": "Просмотреть документ",
|
||||
"features": [
|
||||
"Проверьте выравнивание трубы перед установкой фланца",
|
||||
"Используйте правильный материал прокладки",
|
||||
"Затягивайте болты крест-накрест",
|
||||
"Проверьте целостность уплотнения после сборки"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Все технические детали приведены для справки."
|
||||
}
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
"subPages": {
|
||||
"baza": "Normativ baza",
|
||||
"certificate": "SLT BLOCKFIRE sertifikatlari",
|
||||
"notePP": "PP trubalar va fitinglar bo‘yicha o‘rnatish qo‘llanmasi",
|
||||
"notePP": "PP trubalar va fitinglar o‘rnatish bo‘yicha qo‘llanmasi",
|
||||
"noteTrailer": "Qo‘shma tirkamalar o‘rnatish bo‘yicha qo‘llanma",
|
||||
"noteFlans": "PP flanslar o‘rnatish bo‘yicha qo‘llanma"
|
||||
},
|
||||
@@ -151,6 +151,95 @@
|
||||
}
|
||||
},
|
||||
"bottomText": "Barcha ishlar davlat standartlari va xavfsizlik talablariga muvofiq amalga oshiriladi."
|
||||
},
|
||||
"certificatePage": {
|
||||
"hero": {
|
||||
"label": "Rasmiy tasdiqlar",
|
||||
"title1": "Sertifi",
|
||||
"title2": "katlar",
|
||||
"description": "Bizning mahsulotlar va o'rnatish ishlari sifatini tasdiqlovchi rasmiy sertifikatlar va hujjatlar."
|
||||
},
|
||||
"count": {
|
||||
"suffix": "ta sertifikat",
|
||||
"description": "Kompaniyamiz faoliyati davomida olingan rasmiy sertifikat va tasdiqlash hujjatlari soni."
|
||||
},
|
||||
"card": {
|
||||
"badge": "Rasmiy hujjat",
|
||||
"view": "Ko'rish",
|
||||
"download": "Yuklab olish"
|
||||
},
|
||||
"certificates": {
|
||||
"cert1": {
|
||||
"title": "Sertifikat 1",
|
||||
"desc": "Yong'in xavfsizligi tizimlarini o'rnatish va yetkazib berish faoliyatini amalga oshirish uchun berilgan rasmiy sertifikat."
|
||||
}
|
||||
}
|
||||
},
|
||||
"notePPPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Texnik hujjatlar",
|
||||
"titleLine1": "PP Trubalar",
|
||||
"titleLine2": "va Fitinglar",
|
||||
"title": "PP trubalar va fitinglar o‘rnatish bo‘yicha qo‘llanma",
|
||||
"description": "Ishonchli yong‘in muhofaza tizimlarini ta'minlash uchun polipropilen trubalar va fitinglarni to‘g‘ri o‘rnatish bo‘yicha bosqichma-bosqich ko‘rsatmalar va eng yaxshi amaliyotlar."
|
||||
},
|
||||
"section": {
|
||||
"label": "Batafsil ma'lumot",
|
||||
"cta": "Hujjatni ko'rish",
|
||||
"features": [
|
||||
"Toshqin va axloqsiz trubalardan foydalanmang",
|
||||
"Payvand qilishdan oldin to'g'ri joylashishni ta'minlang",
|
||||
"Tavsiya etilgan muhrlash usullarini qo'llang",
|
||||
"O'rnatishdan keyin ulanishlarni oqish uchun tekshiring"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Barcha texnik tafsilotlar ma'lumot uchun berilgan."
|
||||
}
|
||||
},
|
||||
"noteTrailerPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Texnik hujjatlar",
|
||||
"titleLine1": "Qo‘shma",
|
||||
"titleLine2": "Tirkamalar",
|
||||
"title": "Qo‘shma tirkamalar o‘rnatish bo‘yicha qo‘llanma",
|
||||
"description": "Yong‘in o‘chirish tizimlarida ishlatiladigan tirkamalarni xavfsiz joylashtirish va payvandlash bo‘yicha batafsil ko‘rsatmalar, mustahkam va oqmas ulanishlarni ta'minlash."
|
||||
},
|
||||
"section": {
|
||||
"label": "Batafsil ma'lumot",
|
||||
"cta": "Hujjatni ko'rish",
|
||||
"features": [
|
||||
"To'g'ri tirkama o'lchamini tanlang",
|
||||
"Suvrutani payvandlash uchun tayyorlang",
|
||||
"Ishlab chiqaruvchi payvandlash tartibiga rioya qiling",
|
||||
"Shovotlar yaxlitligini tekshiring"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Barcha texnik tafsilotlar ma'lumot uchun berilgan."
|
||||
}
|
||||
},
|
||||
"noteFlansPage": {
|
||||
"hero": {
|
||||
"eyebrow": "Texnik hujjatlar",
|
||||
"titleLine1": "Nota",
|
||||
"titleLine2": "Flanslar",
|
||||
"title": "PP flanslar o‘rnatish bo‘yicha qo‘llanma",
|
||||
"description": "Polipropilen flanslarni o‘rnatish bo‘yicha to‘liq ko‘rsatmalar, ishontirishni to‘g‘ri muhrlash va ulanish protseduralariga e'tibor qaratilgan, mustahkam quvurlar tarmog‘i uchun."
|
||||
},
|
||||
"section": {
|
||||
"label": "Batafsil ma'lumot",
|
||||
"cta": "Hujjatni ko'rish",
|
||||
"features": [
|
||||
"Flansni o'rnatishdan oldin quvur tekisligini tekshiring",
|
||||
"To'g'ri yostiqcha materialidan foydalaning",
|
||||
"Boltlarni kesma naqshda siqib oling",
|
||||
"Yig'ishdan keyin muhr qoplamasini tekshiring"
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"label": "Barcha texnik tafsilotlar ma'lumot uchun berilgan."
|
||||
}
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
|
||||
Reference in New Issue
Block a user