diff --git a/src/css/common.css b/src/css/common.css
index d091492..0e098a2 100644
--- a/src/css/common.css
+++ b/src/css/common.css
@@ -915,7 +915,6 @@ body{overflow-x:hidden;}
/* ========================================
SI PAGE, RND - PROJECT ARCHIVE SECTION
======================================== */
-.si-archive-wrap .inner-wrap { max-width: none; padding: 0; margin: 0; }
.si_archive { padding:100px 0 120px; max-width:1660px; margin-left: auto; margin-right: 0;}
.si_archive__main { display:flex; align-items:flex-start; gap:46px; }
.si_archive__header { flex: 0 0 320px; padding-top: 24px; }
@@ -1011,103 +1010,97 @@ body{overflow-x:hidden;}
.si_archive__progress { gap: 8px; }
}
-
-/*maintenance page*/
-.mt-intro {display:flex;gap:80px;align-items:center;padding:80px 0 100px;}
-.mt-intro__left {flex:0 0 400px;}
-.mt-intro__right {flex:1;min-width:0;display:flex;justify-content:center;}
-
-.mt-title-line {overflow:hidden;padding-bottom:.06em;margin-bottom:-.06em;}
-.mt-intro__title {font-size:clamp(28px,3vw,42px);font-weight:800;color:var(--color-primary);line-height:1.25;letter-spacing:-.03em;margin:0;}
-
-.mt-intro__desc {font-size:.9rem;color:#666;line-height:1.9;margin:28px 0 36px;word-break:keep-all;}
-
-.mt-intro__cta {display:inline-flex;align-items:center;gap:8px;font-size:.88rem;font-weight:700;color:var(--pink);text-decoration:none;letter-spacing:-.01em;transition:gap .25s;}
-.mt-intro__cta:hover {gap:14px;}
-
-/* ── OPS CENTER ── */
-.mt-ops {position:relative;width:100%;max-width:560px;aspect-ratio:1/1;}
-.mt-ops__svg {width:100%;height:100%;overflow:visible;}
-
-.mt-ops__pulse {transform-origin:320px 320px;}
-
-@keyframes mt-pulse-1 {
- 0% { transform: scale(1); opacity: 1; }
- 100% { transform: scale(3.2); opacity: 0; }
-}
-@keyframes mt-pulse-2 {
- 0% { transform: scale(1); opacity: 1; }
- 100% { transform: scale(2.6); opacity: 0; }
+/* ================================================================
+ Maintenance Page
+ ================================================================ */
+.mt-wrap.sub-content {
+ background: linear-gradient(135deg, #f8f0ff 0%, #ffffff 60%);
}
-
-.mt-ops__pulse--1 {animation: mt-pulse-1 2.8s ease-out infinite;}
-.mt-ops__pulse--2 {animation: mt-pulse-2 2.8s ease-out infinite 1.4s;}
-
-.mt-ops__center {position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:108px;height:108px;border-radius:50%;background:var(--grad-brand);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;box-shadow:0 8px 32px rgba(123,63,160,.35);}
-.mt-ops__center-label {font-size:.95rem;font-weight:900;color:#fff;letter-spacing:.08em;line-height:1;}
-.mt-ops__center-sub {font-size:.6rem;font-weight:700;color:rgba(255,255,255,.7);letter-spacing:.15em;}
-
+.mt-intro { display:flex; gap:60px; align-items:center; padding:80px 0 100px; }
+.mt-intro__left { flex:0 0 400px; }
+.mt-intro__right { flex:1; min-width:0; display:flex; justify-content:right; align-items:center; }
+
+.mt-title-line { overflow:hidden; padding-bottom:.06em; margin-bottom:-.06em; }
+.mt-intro__title { font-size:clamp(28px,3vw,42px); font-weight:800; color:var(--color-primary); line-height:1.25; letter-spacing:-.03em; margin:0; }
+.mt-intro__desc { font-size:.9rem; color:#666; line-height:1.9; margin:28px 0 36px; word-break:keep-all; }
+
+.mt-intro__cta { display:inline-flex; align-items:center; gap:8px; font-size:.88rem; font-weight:700; color:var(--pink); text-decoration:none; letter-spacing:-.01em; transition:gap .25s; }
+.mt-intro__cta:hover { gap:14px; }
+
+/* ── 벤다이어그램 ── */
+.mt-venn { position:relative; width:100%; max-width:640px; }
+.mt-venn__svg { width:100%; height:auto; display:block; overflow:visible; }
+
/* ── KPI 바 ── */
-.mt-kpi {background:var(--color-primary);padding:56px 0;margin:0 0 100px;}
-.mt-kpi__grid {display:grid;grid-template-columns:repeat(4,1fr);gap:0;}
-.mt-kpi__item {display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 16px;border-right:1px solid rgba(255,255,255,.1);text-align:center;}
-.mt-kpi__item:last-child {border-right:none;}
-.mt-kpi__value {font-size:clamp(28px,3.5vw,52px);font-weight:900;color:#fff;letter-spacing:-.04em;line-height:1;}
-.mt-kpi__label {font-size:.78rem;font-weight:500;color:rgba(255,255,255,.45);line-height:1.4;}
-
-/* ── 5컬럼 서비스 ── */
-.mt-services {padding-bottom:120px;}
-.mt-services__grid {display:grid;grid-template-columns:repeat(5,1fr);gap:0;border:1px solid var(--color-primary-soft-border);border-radius:16px;overflow:hidden;}
-
-.mt-service-card {position:relative;display:flex;flex-direction:column;gap:12px;padding:32px 24px 28px;border-right:1px solid var(--color-primary-soft-border);overflow:hidden;transition:background .25s;}
-.mt-service-card:last-child {border-right:none;}
-.mt-service-card:hover {background:var(--color-primary-soft);}
-
-.mt-service-card__img-wrap {width:72px;height:72px;margin-bottom:8px;transition:transform .4s cubic-bezier(.22,1,.36,1);}
-.mt-service-card:hover .mt-service-card__img-wrap {transform:translateY(-6px) scale(1.08);}
-.mt-service-card__img {width:100%;height:100%;object-fit:contain;}
-
-.mt-service-card__num {font-size:.7rem;font-weight:800;letter-spacing:.12em;color:var(--pink);opacity:.8;}
-.mt-service-card__title {font-size:1rem;font-weight:800;color:var(--color-primary);letter-spacing:-.02em;margin:0;}
-.mt-service-card__desc {font-size:.78rem;color:#888;line-height:1.7;word-break:keep-all;margin:0;}
-
-.mt-service-card__line {position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--grad-brand-h);transform:scaleX(0);transform-origin:left;transition:transform .4s cubic-bezier(.22,1,.36,1);}
-.mt-service-card:hover .mt-service-card__line {transform:scaleX(1);}
-
+.mt-kpi { background:var(--color-primary); padding:56px 0; margin:0 0 100px; }
+.mt-kpi__grid { display:grid; grid-template-columns:repeat(4,1fr); gap:0; }
+.mt-kpi__item { display:flex; flex-direction:column; align-items:center; gap:10px; padding:20px 16px; border-right:1px solid rgba(255,255,255,.1); text-align:center; }
+.mt-kpi__item:last-child { border-right:none; }
+.mt-kpi__value { font-size:clamp(28px,3.5vw,52px); font-weight:900; color:#fff; letter-spacing:-.04em; line-height:1; }
+.mt-kpi__label { font-size:.78rem; font-weight:500; color:rgba(255,255,255,.45); line-height:1.4; }
+
+/* ── 5컬럼 서비스 카드 ── */
+.mt-services { padding-bottom:120px; }
+.mt-services__grid { display:grid; grid-template-columns:repeat(5,1fr); gap:0; border:1px solid var(--color-primary-soft-border); border-radius:16px; overflow:hidden; }
+
+.mt-service-card { position:relative; display:flex; flex-direction:column; gap:12px; padding:32px 24px 28px; border-right:1px solid var(--color-primary-soft-border); overflow:hidden; transition:background .25s; }
+.mt-service-card:last-child { border-right:none; }
+.mt-service-card:hover { background:var(--color-primary-soft); }
+
+.mt-service-card__img-wrap { width:72px; height:72px; margin-bottom:8px; transition:transform .4s cubic-bezier(.22,1,.36,1); }
+.mt-service-card:hover .mt-service-card__img-wrap { transform:translateY(-6px) scale(1.08); }
+.mt-service-card__img { width:100%; height:100%; object-fit:contain; }
+
+.mt-service-card__num { font-size:.7rem; font-weight:800; letter-spacing:.12em; color:var(--pink); opacity:.8; }
+.mt-service-card__title { font-size:1rem; font-weight:800; color:var(--color-primary); letter-spacing:-.02em; margin:0; }
+.mt-service-card__desc { font-size:.78rem; color:#888; line-height:1.7; word-break:keep-all; margin:0; }
+
+.mt-service-card__line { position:absolute; bottom:0; left:0; right:0; height:2px; background:var(--grad-brand-h); transform:scaleX(0); transform-origin:left; transition:transform .4s cubic-bezier(.22,1,.36,1); }
+.mt-service-card:hover .mt-service-card__line { transform:scaleX(1); }
+
/* ── Responsive ── */
-@media (max-width: 1280px) {
- .mt-intro {gap:56px;}
- .mt-intro__left {flex:0 0 360px;}
+@media (min-width: 1660px) {
+ .si-archive-wrap .inner-wrap {
+ margin-left: 122.5px;
+ margin-right: 0;
+ padding-right: 0;
+ }
}
+@media (max-width: 1280px) {
+ .mt-intro { gap:40px; }
+ .mt-intro__left { flex:0 0 360px; }
+}
+
@media (max-width: 1024px) {
- .mt-intro {flex-direction:column;gap:48px;padding:60px 0 80px;}
- .mt-intro__left {flex:none;width:100%;}
- .mt-ops {max-width:420px;}
- .mt-services__grid {grid-template-columns:repeat(3,1fr);}
- .mt-service-card:nth-child(3) {border-right:none;}
- .mt-service-card:nth-child(4), .mt-service-card:nth-child(5) {border-top:1px solid var(--color-primary-soft-border);}
- .mt-service-card:nth-child(5) {border-right:none;}
- .mt-kpi__grid {grid-template-columns:repeat(2,1fr);}
- .mt-kpi__item:nth-child(2) {border-right:none;}
- .mt-kpi__item:nth-child(3), .mt-kpi__item:nth-child(4) {border-top:1px solid rgba(255,255,255,.1);}
- .mt-kpi__item:nth-child(4) {border-right:none;}
+ .mt-intro { flex-direction:column; gap:48px; padding:60px 0 80px; }
+ .mt-intro__left { flex:none; width:100%; }
+ .mt-venn { max-width:460px; }
+ .mt-services__grid { grid-template-columns:repeat(3,1fr); }
+ .mt-service-card:nth-child(3) { border-right:none; }
+ .mt-service-card:nth-child(4), .mt-service-card:nth-child(5) { border-top:1px solid var(--color-primary-soft-border); }
+ .mt-service-card:nth-child(5) { border-right:none; }
+ .mt-kpi__grid { grid-template-columns:repeat(2,1fr); }
+ .mt-kpi__item:nth-child(2) { border-right:none; }
+ .mt-kpi__item:nth-child(3), .mt-kpi__item:nth-child(4) { border-top:1px solid rgba(255,255,255,.1); }
+ .mt-kpi__item:nth-child(4) { border-right:none; }
}
-
+
@media (max-width: 768px) {
- .mt-intro {padding:48px 0 64px;}
- .mt-ops {max-width:340px;}
- .mt-services__grid {grid-template-columns:repeat(2,1fr);}
- .mt-service-card:nth-child(2n) {border-right:none;}
- .mt-service-card:nth-child(3) {border-right:1px solid var(--color-primary-soft-border);}
- .mt-service-card:nth-child(n+3) {border-top:1px solid var(--color-primary-soft-border);}
- .mt-service-card:nth-child(5) {border-right:none;grid-column:span 2;}
- .mt-kpi {margin-bottom:64px;}
+ .mt-intro { padding:48px 0 64px; }
+ .mt-venn { max-width:340px; }
+ .mt-services__grid { grid-template-columns:repeat(2,1fr); }
+ .mt-service-card:nth-child(2n) { border-right:none; }
+ .mt-service-card:nth-child(3) { border-right:1px solid var(--color-primary-soft-border); }
+ .mt-service-card:nth-child(n+3) { border-top:1px solid var(--color-primary-soft-border); }
+ .mt-service-card:nth-child(5) { border-right:none; grid-column:span 2; }
+ .mt-kpi { margin-bottom:64px; }
}
-
+
@media (max-width: 480px) {
- .mt-services__grid {grid-template-columns:1fr;}
- .mt-service-card {border-right:none !important;}
- .mt-service-card:nth-child(n+2) {border-top:1px solid var(--color-primary-soft-border);}
- .mt-service-card:nth-child(5) {grid-column:span 1;}
-}
\ No newline at end of file
+ .mt-services__grid { grid-template-columns:1fr; }
+ .mt-service-card { border-right:none !important; }
+ .mt-service-card:nth-child(n+2) { border-top:1px solid var(--color-primary-soft-border); }
+ .mt-service-card:nth-child(5) { grid-column:span 1; }
+}
+
\ No newline at end of file
diff --git a/src/pages/business/MaintenancePage.jsx b/src/pages/business/MaintenancePage.jsx
index a7d064d..76a99e3 100644
--- a/src/pages/business/MaintenancePage.jsx
+++ b/src/pages/business/MaintenancePage.jsx
@@ -1,5 +1,6 @@
-import { useRef } from "react";
-import { motion, useInView, useAnimationFrame } from "framer-motion";
+import { useRef, useEffect, useState } from "react";
+import { motion, useInView } from "framer-motion";
+import { gsap } from "gsap";
import SubHero from "../../components/SubHero";
import useFadeIn from "../../hooks/useFadeIn";
@@ -11,7 +12,55 @@ const BUSINESS_NAV = [
{ label: "운영 · 유지보수", to: "/business/maintenance" },
];
-const SERVICES = [
+const CIRCLES = [
+ {
+ id: "c0",
+ title: "모니터링",
+ items: [
+ "시스템·네트워크 전 계층 감시",
+ "이상 징후 선제 포착",
+ "24/7 실시간 알람",
+ ],
+ grad: ["#d94889", "#a855f7"],
+ },
+ {
+ id: "c1",
+ title: "장애 대응",
+ items: ["즉각적인 원인 분석", "신속한 시스템 복구", "재발 방지 체계 수립"],
+ grad: ["#a855f7", "#6366f1"],
+ },
+ {
+ id: "c2",
+ title: "보안 관리",
+ items: ["정기 취약점 점검", "패치 및 업데이트 관리", "외부 위협 차단"],
+ grad: ["#6366f1", "#3b82f6"],
+ },
+ {
+ id: "c3",
+ title: "기술 지원",
+ items: [
+ "기술 문의 신속 응대",
+ "가이드 및 교육 제공",
+ "고객 역량 강화 지원",
+ ],
+ grad: ["#3b82f6", "#06b6d4"],
+ },
+ {
+ id: "c4",
+ title: "지속적 개선",
+ items: ["정기 리포트 분석", "운영 효율 최적화", "서비스 품질 지속 향상"],
+ grad: ["#06b6d4", "#d94889"],
+ },
+];
+
+const KPI = [
+ { value: "99.9%", label: "서비스 가용성" },
+ { value: "24/7", label: "365일 실시간 운영" },
+ { value: "10m 24s", label: "평균 응답 시간" },
+ { value: "100%", label: "SLA 준수율" },
+];
+
+const SERVICES_CARD = [
{
num: "01",
title: "모니터링",
@@ -44,113 +93,373 @@ const SERVICES = [
},
];
-const KPI = [
- { value: "99.9%", label: "서비스 가용성" },
- { value: "24/7", label: "365일 실시간 운영" },
- { value: "10m 24s", label: "평균 응답 시간" },
- { value: "100%", label: "SLA 준수율" },
-];
+/* ── KPI 카운트업 ── */
+function KpiItem({ value, label, inView, delay }) {
+ const valRef = useRef(null);
+ const hasAnimated = useRef(false);
+ useEffect(() => {
+ if (!inView || hasAnimated.current) return;
+ hasAnimated.current = true;
+ const el = valRef.current;
+ const match = value.match(/^([^0-9]*)([0-9]+\.?[0-9]*)(.*)$/);
+ if (!match) {
+ gsap.from(el, { opacity: 0, y: 10, duration: 0.6, delay });
+ return;
+ }
+ const prefix = match[1],
+ num = parseFloat(match[2]),
+ suffix = match[3];
+ const decimals = match[2].includes(".") ? match[2].split(".")[1].length : 0;
+ const obj = { val: 0 };
+ gsap.to(obj, {
+ val: num,
+ duration: 1.8,
+ delay,
+ ease: "power3.out",
+ onUpdate: () => {
+ el.textContent = prefix + obj.val.toFixed(decimals) + suffix;
+ },
+ onComplete: () => {
+ el.textContent = value;
+ },
+ });
+ }, [inView]); // eslint-disable-line
+ return (
+