Help
RSS
API
Feed
Maltego
Contact
Domain > safeqrcall.com
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2026-02-22
172.67.70.140
(
ClassC
)
Port 443
HTTP/1.1 200 OKDate: Sun, 22 Feb 2026 21:30:47 GMTContent-Type: text/html; charsetutf-8Transfer-Encoding: chunkedConnection: keep-aliveServer: cloudflareNel: {report_to:cf-nel,success_fraction:0.0,max_age:604800}X-Powered-By: ExpressCache-Control: public, max-age0Last-Modified: Fri, 30 Jan 2026 11:37:51 GMTvary: accept-encodingX-Frame-Options: SAMEORIGINX-Content-Type-Options: nosniffReport-To: {group:cf-nel,max_age:604800,endpoints:{url:https://a.nel.cloudflare.com/report/v4?spm8HkDbi20uhSNDLPLUqPfISm2SDoKsBmIlKrtEjteGkiIop1dKj6QOgoA0LEvWSli5cnXTox%2FRuA6T5hse4tTJXw6MLBI5hAZbB9ms%3D}}cf-cache-status: DYNAMICCF-RAY: 9d21962958461c37-PDX !DOCTYPE html>html langko>head> meta charsetUTF-8> meta nameviewport contentwidthdevice-width, initial-scale1.0, user-scalableyes, minimum-scale1.0, maximum-scale5.0> !-- SEO Meta Tags --> meta namedescription contentQR코드로 지키는 내 개인정보 - SafeQRCall. 안심번호로 실제 전화번호를 보호하세요. 평생 무료 사용, 문자 수신 가능, 최대 4개 번호 등록.> meta namekeywords content안심번호, QR코드, 개인정보보호, 가상번호, 050번호, 주차스티커, 전화번호숨기기> meta nameauthor contentSafeQRCall> meta namerobots contentindex, follow> !-- Open Graph / Facebook --> meta propertyog:type contentwebsite> meta propertyog:url contenthttps://safeqrcall.com/> meta propertyog:title contentSafeQRCall - QR코드로 지키는 내 개인정보> meta propertyog:description content안심번호로 실제 전화번호를 보호하세요. 평생 무료 사용, 문자 수신 가능.> meta propertyog:image contenthttps://safeqrcall.com/uploads/logos/safeqrcall_light_mode_logo_240x80px.svg> !-- Twitter --> meta propertytwitter:card contentsummary_large_image> meta propertytwitter:url contenthttps://safeqrcall.com/> meta propertytwitter:title contentSafeQRCall - QR코드로 지키는 내 개인정보> meta propertytwitter:description content안심번호로 실제 전화번호를 보호하세요. 평생 무료 사용, 문자 수신 가능.> title>SafeQRCall - QR코드로 지키는 내 개인정보 | 안심번호 서비스/title> !-- Favicon --> link relicon typeimage/svg+xml href/favicon.svg> !-- Preconnect for performance --> link relpreconnect hrefhttps://unpkg.com> link reldns-prefetch hrefhttps://unpkg.com> !-- AOS Animation Library --> link relpreload hrefhttps://unpkg.com/aos@2.3.1/dist/aos.css asstyle> link hrefhttps://unpkg.com/aos@2.3.1/dist/aos.css relstylesheet> style> /* Reset & Base */ * { margin: 0; padding: 0; box-sizing: border-box; } html { scroll-behavior: smooth; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Noto Sans KR, Malgun Gothic, sans-serif; line-height: 1.6; color: #ffffff; background: #0a0e27; overflow-x: hidden; } /* 다크 + 네온 컬러 팔레트 */ :root { /* 다크 베이스 */ --bg-dark: #0a0e27; --bg-darker: #060913; --bg-card: rgba(26, 32, 56, 0.8); /* 네온 컬러 */ --neon-cyan: #00f5ff; --neon-pink: #ff006e; --neon-purple: #8b5cf6; --neon-green: #00ff88; /* 그라데이션 */ --gradient-main: linear-gradient(135deg, #00f5ff 0%, #8b5cf6 50%, #ff006e 100%); --gradient-card: linear-gradient(135deg, rgba(0, 245, 255, 0.1) 0%, rgba(139, 92, 246, 0.1) 100%); /* 텍스트 */ --text-primary: #ffffff; --text-secondary: #a0aec0; --text-glow: 0 0 20px rgba(0, 245, 255, 0.5); /* 버튼 */ --btn-primary: #00f5ff; --btn-hover: #00d4e0; } /* 공통 스타일 */ .container { max-width: 1200px; margin: 0 auto; padding: 0 20px; } /* Hero 섹션 */ .hero { position: relative; min-height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--bg-dark); } /* 비디오 배경 (기본 숨김, JavaScript로 제어) */ .hero-video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.3; z-index: 1; display: none; /* 기본 숨김 */ } /* 비디오 오버레이 (그라데이션) */ .hero-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( 135deg, rgba(0, 245, 255, 0.1) 0%, rgba(10, 14, 39, 0.8) 50%, rgba(255, 0, 110, 0.1) 100% ); z-index: 2; } /* 네온 그리드 효과 (애니메이션 배경 - 기본 표시) */ .hero-grid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(rgba(0, 245, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 245, 255, 0.05) 1px, transparent 1px); background-size: 50px 50px; z-index: 1; display: block; /* 기본 표시 */ animation: gridMove 20s linear infinite; } @keyframes gridMove { 0% { transform: perspective(500px) rotateX(60deg) translateZ(0); background-position: 0 0; } 100% { transform: perspective(500px) rotateX(60deg) translateZ(0); background-position: 50px 50px; } } /* 네온 파티클 효과 */ .hero-grid::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 20% 50%, rgba(0, 245, 255, 0.15) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(139, 92, 246, 0.15) 0%, transparent 50%), radial-gradient(circle at 40% 20%, rgba(255, 0, 110, 0.15) 0%, transparent 50%); animation: particleMove 15s ease-in-out infinite; } @keyframes particleMove { 0%, 100% { transform: translate(0, 0); opacity: 0.5; } 25% { transform: translate(30px, 50px); opacity: 0.8; } 50% { transform: translate(-20px, 30px); opacity: 0.6; } 75% { transform: translate(40px, -30px); opacity: 0.9; } } /* 네온 라인 효과 */ .hero-grid::after { content: ; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient( 90deg, transparent 0%, rgba(0, 245, 255, 0.1) 50%, transparent 100% ); animation: scanLine 10s linear infinite; } @keyframes scanLine { 0% { left: -100%; } 100% { left: 100%; } } /* Hero 콘텐츠 */ .hero-content { position: relative; z-index: 3; text-align: center; padding: 40px 20px; max-width: 900px; } /* 로고 */ .hero-logo { margin-bottom: 40px; animation: fadeInDown 1s ease-out; } .hero-logo img { width: 185px; height: auto; filter: drop-shadow(0 0 20px rgba(0, 245, 255, 0.5)); } /* 타이틀 */ .hero-title { font-size: 56px; font-weight: 800; line-height: 1.2; margin-bottom: 30px; background: var(--gradient-main); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; text-shadow: var(--text-glow); animation: fadeInUp 1s ease-out 0.2s both; } /* 서브카피 */ .hero-subtitle { font-size: 24px; line-height: 1.6; color: var(--text-secondary); margin-bottom: 50px; animation: fadeInUp 1s ease-out 0.4s both; } .hero-subtitle strong { color: var(--neon-cyan); font-weight: 700; } /* CTA 버튼 */ .hero-cta { display: inline-block; padding: 18px 50px; font-size: 20px; font-weight: 700; color: var(--bg-dark); background: var(--btn-primary); border: none; border-radius: 50px; text-decoration: none; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 0 30px rgba(0, 245, 255, 0.5); animation: fadeInUp 1s ease-out 0.6s both; } .hero-cta:hover { background: var(--btn-hover); transform: translateY(-5px); box-shadow: 0 10px 40px rgba(0, 245, 255, 0.7); } /* 스크롤 다운 인디케이터 */ .scroll-indicator { position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%); z-index: 3; animation: bounce 2s infinite; } .scroll-indicator svg { width: 30px; height: 30px; fill: var(--neon-cyan); opacity: 0.7; } /* 애니메이션 */ @keyframes fadeInDown { from { opacity: 0; transform: translateY(-30px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } @keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translateX(-50%) translateY(0); } 40% { transform: translateX(-50%) translateY(-20px); } 60% { transform: translateX(-50%) translateY(-10px); } } /* 반응형 (모바일 First) */ /* 모바일 기본 (375px 이하) */ @media (max-width: 767px) { .hero-title { font-size: 36px; } .hero-subtitle { font-size: 18px; } .hero-cta { padding: 16px 40px; font-size: 18px; } .hero-logo img { width: 139px; height: auto; } } /* 태블릿 (768px ~ 1023px) */ @media (min-width: 768px) and (max-width: 1023px) { .hero-title { font-size: 48px; } .hero-subtitle { font-size: 22px; } } /* 데스크탑 (1024px 이상) */ @media (min-width: 1024px) { .hero-title { font-size: 56px; } .hero-subtitle { font-size: 24px; } } /* Problem 섹션 */ .section-problem { min-height: 100vh; padding: 100px 20px; background: var(--bg-darker); position: relative; overflow: hidden; } /* 배경 그라데이션 */ .section-problem::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at top right, rgba(255, 0, 110, 0.1), transparent 50%), radial-gradient(circle at bottom left, rgba(139, 92, 246, 0.1), transparent 50%); z-index: 0; } .problem-content { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; } /* 섹션 헤더 */ .section-header { text-align: center; margin-bottom: 80px; } .section-subtitle { font-size: 18px; color: var(--neon-cyan); font-weight: 600; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 20px; } .section-title { font-size: 48px; font-weight: 800; line-height: 1.3; color: var(--text-primary); margin-bottom: 30px; } .section-title .highlight { background: var(--gradient-main); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .section-description { font-size: 20px; color: var(--text-secondary); line-height: 1.6; max-width: 800px; margin: 0 auto; } /* 문제 카드 그리드 */ .problem-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; margin-bottom: 60px; } /* 문제 카드 */ .problem-card { background: var(--bg-card); border: 1px solid rgba(255, 0, 110, 0.2); border-radius: 20px; padding: 40px 30px; text-align: center; transition: all 0.3s ease; backdrop-filter: blur(10px); position: relative; overflow: hidden; } .problem-card::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--gradient-card); opacity: 0; transition: opacity 0.3s ease; z-index: -1; } .problem-card:hover { transform: translateY(-10px); border-color: var(--neon-pink); box-shadow: 0 20px 40px rgba(255, 0, 110, 0.3); } .problem-card:hover::before { opacity: 1; } /* 문제 아이콘 */ .problem-icon { font-size: 64px; margin-bottom: 25px; display: inline-block; animation: float 3s ease-in-out infinite; } @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } .problem-card:nth-child(2) .problem-icon { animation-delay: 0.5s; } .problem-card:nth-child(3) .problem-icon { animation-delay: 1s; } /* 문제 제목 */ .problem-title { font-size: 22px; font-weight: 700; color: var(--text-primary); margin-bottom: 15px; line-height: 1.4; } /* 문제 설명 */ .problem-desc { font-size: 16px; color: var(--text-secondary); line-height: 1.6; } /* 결론 박스 */ .problem-conclusion { background: linear-gradient(135deg, rgba(255, 0, 110, 0.1), rgba(139, 92, 246, 0.1)); border: 2px solid var(--neon-pink); border-radius: 20px; padding: 40px; text-align: center; margin-top: 60px; } .problem-conclusion-text { font-size: 28px; font-weight: 700; color: var(--text-primary); line-height: 1.5; } .problem-conclusion-text .emphasis { color: var(--neon-pink); text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 5px; } /* 반응형 */ @media (max-width: 767px) { .section-problem { padding: 60px 20px; } .section-title { font-size: 32px; } .section-description { font-size: 16px; } .problem-grid { grid-template-columns: 1fr; gap: 20px; } .problem-card { padding: 30px 20px; } .problem-icon { font-size: 48px; } .problem-title { font-size: 18px; } .problem-desc { font-size: 14px; } .problem-conclusion { padding: 30px 20px; } .problem-conclusion-text { font-size: 20px; } } @media (min-width: 768px) and (max-width: 1023px) { .section-title { font-size: 40px; } .problem-grid { grid-template-columns: repeat(2, 1fr); } } /* Solution 섹션 */ .section-solution { min-height: 100vh; padding: 100px 20px; background: var(--bg-dark); position: relative; overflow: hidden; } /* 배경 그라데이션 */ .section-solution::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at top left, rgba(0, 245, 255, 0.1), transparent 50%), radial-gradient(circle at bottom right, rgba(139, 92, 246, 0.1), transparent 50%); z-index: 0; } .solution-content { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; } /* 인터랙티브 데모 */ .demo-container { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; margin-top: 60px; } /* QR 스캔 시뮬레이션 */ .qr-simulation { position: relative; } .phone-mockup { position: relative; width: 100%; max-width: 350px; margin: 0 auto; aspect-ratio: 9 / 19; background: linear-gradient(145deg, #1a1f3a, #0d1025); border-radius: 40px; padding: 15px; box-shadow: 0 30px 60px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1); } .phone-screen { width: 100%; height: 100%; background: var(--bg-dark); border-radius: 30px; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } /* QR 코드 */ .qr-code { width: 200px; height: 200px; background: white; border-radius: 20px; padding: 20px; box-shadow: 0 10px 30px rgba(0, 245, 255, 0.3); animation: pulse 2s ease-in-out infinite; } @keyframes pulse { 0%, 100% { transform: scale(1); box-shadow: 0 10px 30px rgba(0, 245, 255, 0.3); } 50% { transform: scale(1.05); box-shadow: 0 15px 40px rgba(0, 245, 255, 0.5); } } .qr-code svg { width: 100%; height: 100%; } .scan-text { margin-top: 30px; font-size: 18px; color: var(--neon-cyan); font-weight: 600; text-align: center; } /* 프로세스 단계 */ .process-steps { display: flex; flex-direction: column; gap: 30px; } .process-step { display: flex; gap: 20px; align-items: flex-start; } .step-number { flex-shrink: 0; width: 60px; height: 60px; background: var(--gradient-main); border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 28px; font-weight: 800; color: white; box-shadow: 0 5px 20px rgba(0, 245, 255, 0.4); } .step-content { flex: 1; padding-top: 8px; } .step-title { font-size: 24px; font-weight: 700; color: var(--text-primary); margin-bottom: 10px; } .step-desc { font-size: 16px; color: var(--text-secondary); line-height: 1.6; } /* 화살표 애니메이션 */ .arrow-icon { width: 40px; height: 40px; margin: 10px auto; opacity: 0.5; animation: bounce-arrow 2s ease-in-out infinite; } @keyframes bounce-arrow { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } } .arrow-icon svg { width: 100%; height: 100%; fill: var(--neon-cyan); } /* 반응형 */ @media (max-width: 767px) { .section-solution { padding: 60px 20px; } .demo-container { grid-template-columns: 1fr; gap: 40px; } .phone-mockup { max-width: 280px; } .qr-code { width: 150px; height: 150px; } .scan-text { font-size: 16px; } .step-number { width: 50px; height: 50px; font-size: 24px; } .step-title { font-size: 20px; } .step-desc { font-size: 14px; } } @media (min-width: 768px) and (max-width: 1023px) { .demo-container { gap: 40px; } } /* Features 섹션 */ .section-features { min-height: 100vh; padding: 100px 20px; background: var(--bg-darker); position: relative; overflow: hidden; } /* 배경 그라데이션 */ .section-features::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at center, rgba(139, 92, 246, 0.1), transparent 70%); z-index: 0; } .features-content { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; } /* Features 그리드 */ .features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 30px; margin-top: 60px; } /* Feature 카드 */ .feature-card { background: var(--bg-card); border: 1px solid rgba(139, 92, 246, 0.2); border-radius: 20px; padding: 40px 30px; text-align: center; transition: all 0.4s ease; backdrop-filter: blur(10px); position: relative; overflow: hidden; } /* 카드 배경 그라데이션 */ .feature-card::before { content: ; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: conic-gradient( from 0deg at 50% 50%, transparent 0deg, rgba(139, 92, 246, 0.1) 90deg, transparent 180deg ); opacity: 0; transition: all 0.6s ease; animation: rotate 4s linear infinite; animation-play-state: paused; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .feature-card:hover::before { opacity: 1; animation-play-state: running; } .feature-card:hover { transform: translateY(-15px) scale(1.02); border-color: var(--neon-purple); box-shadow: 0 25px 50px rgba(139, 92, 246, 0.4); } /* Feature 아이콘 */ .feature-icon { width: 80px; height: 80px; margin: 0 auto 25px; background: var(--gradient-main); border-radius: 20px; display: flex; align-items: center; justify-content: center; font-size: 40px; box-shadow: 0 10px 30px rgba(139, 92, 246, 0.3); transition: all 0.4s ease; } .feature-card:hover .feature-icon { transform: rotateY(360deg); box-shadow: 0 15px 40px rgba(139, 92, 246, 0.6); } /* Feature 제목 */ .feature-title { font-size: 22px; font-weight: 700; color: var(--text-primary); margin-bottom: 15px; line-height: 1.4; } /* Feature 설명 */ .feature-desc { font-size: 16px; color: var(--text-secondary); line-height: 1.6; } /* 특별 배지 */ .feature-badge { position: absolute; top: 20px; right: 20px; background: var(--neon-green); color: var(--bg-dark); font-size: 12px; font-weight: 700; padding: 6px 12px; border-radius: 20px; text-transform: uppercase; letter-spacing: 1px; box-shadow: 0 5px 15px rgba(0, 255, 136, 0.4); } /* 반응형 */ @media (max-width: 767px) { .section-features { padding: 60px 20px; } .features-grid { grid-template-columns: 1fr; gap: 20px; } .feature-card { padding: 30px 20px; } .feature-icon { width: 70px; height: 70px; font-size: 35px; } .feature-title { font-size: 20px; } .feature-desc { font-size: 14px; } } @media (min-width: 768px) and (max-width: 1023px) { .features-grid { grid-template-columns: repeat(2, 1fr); } } /* FAQ 섹션 */ .section-faq { min-height: 100vh; padding: 100px 20px; background: var(--bg-dark); position: relative; overflow: hidden; } /* 배경 그라데이션 */ .section-faq::before { content: ; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at bottom left, rgba(0, 245, 255, 0.1), transparent 50%), radial-gradient(circle at top right, rgba(255, 0, 110, 0.1), transparent 50%); z-index: 0; } .faq-content { position: relative; z-index: 1; max-width: 900px; margin: 0 auto; } /* FAQ 아이템 */ .faq-list { margin-top: 60px; display: flex; flex-direction: column; gap: 20px; } .faq-item { background: var(--bg-card); border: 1px solid rgba(0, 245, 255, 0.2); border-radius: 15px; overflow: hidden; transition: all 0.3s ease; backdrop-filter: blur(10px); } .faq-item:hover { border-color: var(--neon-cyan); box-shadow: 0 10px 30px rgba(0, 245, 255, 0.2); } /* FAQ 질문 (버튼) */ .faq-question { width: 100%; padding: 25px 30px; background: transparent; border: none; color: var(--text-primary); font-size: 18px; font-weight: 700; text-align: left; cursor: pointer; display: flex; justify-content: space-between; align-items: center; transition: all 0.3s ease; } .faq-question:hover { color: var(--neon-cyan); } .faq-question-text { flex: 1; line-height: 1.5; } /* FAQ 아이콘 */ .faq-icon { flex-shrink: 0; width: 30px; height: 30px; margin-left: 20px; display: flex; align-items: center; justify-content: center; font-size: 24px; color: var(--neon-cyan); transition: transform 0.3s ease; } .faq-item.active .faq-icon { transform: rotate(180deg); } /* FAQ 답변 */ .faq-answer { max-height: 0; overflow: hidden; transition: max-height 0.4s ease, padding 0.4s ease; padding: 0 30px; } .faq-item.active .faq-answer { max-height: 500px; padding: 25px 30px 25px 30px; } .faq-answer-text { font-size: 16px; line-height: 1.8; color: var(--text-secondary); } /* FAQ 반응형 */ @media (max-width: 767px) { .section-faq { padding: 60px 20px; } .faq-question { padding: 20px; font-size: 16px; } .faq-icon { width: 25px; height: 25px; font-size: 20px; margin-left: 15px; } .faq-answer { padding: 0 20px; } .faq-item.active .faq-answer { padding: 20px 20px 20px 20px; } .faq-answer-text { font-size: 14px; } } /* CTA 섹션 */ .section-cta { padding: 120px 20px; background: linear-gradient(135deg, rgba(0, 245, 255, 0.1) 0%, rgba(139, 92, 246, 0.15) 50%, rgba(255, 0, 110, 0.1) 100%); position: relative; overflow: hidden; } /* CTA 배경 효과 */ .section-cta::before { content: ; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 800px; height: 800px; background: radial-gradient(circle, rgba(0, 245, 255, 0.2), transparent 70%); animation: pulse-bg 4s ease-in-out infinite; } @keyframes pulse-bg { 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; } 50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.8; } } .cta-content { position: relative; z-index: 1; max-width: 800px; margin: 0 auto; text-align: center; } .cta-title { font-size: 48px; font-weight: 800; line-height: 1.3; margin-bottom: 30px; background: var(--gradient-main); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .cta-description { font-size: 20px; line-height: 1.6; color: var(--text-secondary); margin-bottom: 50px; } .cta-button { display: inline-block; padding: 22px 60px; font-size: 22px; font-weight: 700; color: var(--bg-dark); background: var(--gradient-main); border: none; border-radius: 50px; text-decoration: none; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 15px 40px rgba(0, 245, 255, 0.4); position: relative; overflow: hidden; } .cta-button::before { content: ; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 0; height: 0; background: rgba(255, 255, 255, 0.3); border-radius: 50%; transition: width 0.6s ease, height 0.6s ease; } .cta-button:hover::before { width: 300px; height: 300px; } .cta-button:hover { transform: translateY(-5px) scale(1.05); box-shadow: 0 20px 50px rgba(0, 245, 255, 0.6); } .cta-button-text { position: relative; z-index: 1; } /* CTA 반응형 */ @media (max-width: 767px) { .section-cta { padding: 80px 20px; } .cta-title { font-size: 32px; } .cta-description { font-size: 16px; } .cta-button { padding: 18px 40px; font-size: 18px; } } /* Footer */ .footer { padding: 60px 20px 30px; background: var(--bg-darker); border-top: 1px solid rgba(0, 245, 255, 0.1); } .footer-content { max-width: 1200px; margin: 0 auto; } .footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 40px; margin-bottom: 40px; } .footer-section-title { font-size: 18px; font-weight: 700; color: var(--neon-cyan); margin-bottom: 20px; cursor: pointer; display: flex; align-items: center; justify-content: space-between; user-select: none; } .footer-accordion-icon { font-size: 14px; transition: transform 0.3s ease; } .footer-section.active .footer-accordion-icon { transform: rotate(180deg); } .footer-links-wrapper { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .footer-section.active .footer-links-wrapper { max-height: 300px; } .footer-logo { margin-bottom: 20px; } .footer-logo img { height: 25px; width: auto; } .footer-description { font-size: 14px; line-height: 1.6; color: var(--text-secondary); margin-bottom: 30px; } .footer-company-info { font-size: 14px; line-height: 1.8; color: var(--text-secondary); } .footer-company-info p { margin: 8px 0; } .footer-company-info strong { color: var(--neon-cyan); font-weight: 600; min-width: 90px; display: inline-block; } .footer-about { max-width: 400px; } .footer-links { list-style: none; padding: 0; margin: 0; } .footer-links li { margin-bottom: 12px; } .footer-links a { font-size: 14px; color: var(--text-secondary); text-decoration: none; transition: color 0.3s ease; } .footer-links a:hover { color: var(--neon-cyan); } .footer-bottom { padding-top: 30px; border-top: 1px solid rgba(255, 255, 255, 0.1); text-align: center; } .footer-copyright { font-size: 14px; color: var(--text-secondary); } /* Footer 반응형 */ @media (max-width: 1024px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 30px; } .footer-about { grid-column: 1 / -1; } } @media (max-width: 767px) { .footer { padding: 40px 20px 20px; } .footer-grid { grid-template-columns: 1fr; gap: 30px; } .footer-about { grid-column: auto; } } /* 접근성 개선 */ /* 포커스 표시 개선 */ a:focus, button:focus { outline: 2px solid var(--neon-cyan); outline-offset: 2px; } /* 터치 영역 최적화 (최소 44x44px) */ .faq-question, .hero-cta, .cta-button, .footer-links a { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; } /* 로딩 인디케이터 */ .loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--bg-dark); display: flex; align-items: center; justify-content: center; z-index: 9999; opacity: 1; transition: opacity 0.5s ease; } .loading-overlay.hidden { opacity: 0; pointer-events: none; } .loading-spinner { width: 60px; height: 60px; border: 4px solid rgba(0, 245, 255, 0.1); border-top: 4px solid var(--neon-cyan); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* 성능 최적화 - GPU 가속 */ .hero-content, .problem-card, .feature-card, .faq-item, .phone-mockup { transform: translateZ(0); will-change: transform; } /* 부드러운 스크롤 */ @media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } } /* 움직임 감소 선호 사용자 지원 */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } /* 고대비 모드 지원 */ @media (prefers-contrast: high) { :root { --neon-cyan: #00ffff; --neon-pink: #ff0080; --neon-purple: #a855f7; } .problem-card, .feature-card, .faq-item { border-width: 2px; } } /* 화면 크기별 추가 최적화 */ /* 매우 작은 모바일 (320px ~ 374px) */ @media (max-width: 374px) { .hero-title { font-size: 28px; } .hero-subtitle { font-size: 16px; } .section-title { font-size: 28px; } .cta-title { font-size: 28px; } } /* 큰 데스크탑 (1440px 이상) */ @media (min-width: 1440px) { .hero-title { font-size: 64px; } .section-title { font-size: 52px; } .cta-title { font-size: 52px; } } /* 초대형 화면 (1920px 이상) */ @media (min-width: 1920px) { .container, .hero-content, .problem-content, .solution-content, .features-content, .faq-content, .cta-content, .footer-content { max-width: 1400px; } } /* 다크모드 자동 감지 (미래 대비) */ @media (prefers-color-scheme: light) { /* 라이트 모드는 현재 지원하지 않음 */ /* 필요시 추가 가능 */ } /style>/head>body>a hrefhttps://safeqrcall.com/cdn-cgi/content?idTs0TJtgRnTcDTe5BR7sbswqK_DNJNW1Ayj.U30j5gVA-1771795846.6165786-1.0.1.1-x7qPs_1EdTE8lE.h0wyzZt8GUbB.dVRlAD_.rRvSXZg aria-hiddentrue relnofollow noopener styledisplay: none !important; visibility: hidden !important>/a> !-- 로딩 인디케이터 --> div classloading-overlay idloadingOverlay rolestatus aria-label페이지 로딩 중> div classloading-spinner aria-hiddentrue>/div> /div> !-- Hero 섹션 --> section classhero idhero rolebanner aria-label메인 히어로 섹션> !-- 비디오 배경 (실제 비디오 또는 애니메이션 폴백) --> video classhero-video autoplay muted loop playsinline poster idheroVideo> !-- 비디오 소스는 사용자가 업로드 시 추가 가능 --> !-- source src/uploads/videos/hero-background.mp4 typevideo/mp4> --> !-- source src/uploads/videos/hero-background.webm typevideo/webm> --> /video> !-- 애니메이션 그리드 (비디오 없을 때 폴백) --> div classhero-grid idheroGrid>/div> !-- 오버레이 --> div classhero-overlay>/div> !-- 콘텐츠 --> div classhero-content> !-- 로고 --> div classhero-logo> img src/uploads/logos/homepage_main_logo.png altSafeQRCall data-logohero> /div> !-- 타이틀 --> h1 classhero-title> !-- CMS에서 로드 --> /h1> !-- 서브카피 --> p classhero-subtitle> !-- CMS에서 로드 --> /p> !-- CTA 버튼 --> a href#problem classhero-cta> !-- CMS에서 로드 --> /a> /div> !-- 스크롤 다운 인디케이터 --> div classscroll-indicator rolebutton tabindex0 aria-label아래로 스크롤> svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 24 24 aria-hiddentrue> path dM12 16l-6-6h12l-6 6z/> /svg> /div> /section> !-- Problem 섹션 --> section classsection-problem idproblem idmain-content rolemain aria-label문제점 섹션> div classproblem-content> !-- 섹션 헤더 --> div classsection-header data-aosfade-up> div classsection-subtitle>Problem/div> h2 classsection-title> !-- CMS에서 로드 --> /h2> /div> !-- 문제 카드 그리드 --> div classproblem-grid> !-- 문제 1 --> div classproblem-card data-aosfade-up data-aos-delay100> div classproblem-icon>📞/div> h3 classproblem-title> !-- CMS에서 로드 --> /h3> p classproblem-desc> !-- CMS에서 로드 --> /p> /div> !-- 문제 2 --> div classproblem-card data-aosfade-up data-aos-delay200> div classproblem-icon>🔍/div> h3 classproblem-title> !-- CMS에서 로드 --> /h3> p classproblem-desc> !-- CMS에서 로드 --> /p> /div> !-- 문제 3 --> div classproblem-card data-aosfade-up data-aos-delay300> div classproblem-icon>😰/div> h3 classproblem-title> !-- CMS에서 로드 --> /h3> p classproblem-desc> !-- CMS에서 로드 --> /p> /div> /div> !-- 결론 박스 --> div classproblem-conclusion data-aoszoom-in data-aos-delay400> p classproblem-conclusion-text> !-- CMS에서 로드 --> /p> /div> /div> /section> !-- AOS Animation Library --> !-- Solution 섹션 --> section classsection-solution idsolution roleregion aria-label해결책 섹션> div classsolution-content> !-- 섹션 헤더 --> div classsection-header data-aosfade-up> div classsection-subtitle>Solution/div> h2 classsection-title> !-- CMS에서 로드 --> /h2> p classsection-description> !-- CMS에서 로드 --> /p> /div> !-- 인터랙티브 데모 --> div classdemo-container> !-- 왼쪽: QR 스캔 시뮬레이션 --> div classqr-simulation data-aosfade-right> div classphone-mockup> div classphone-screen> div classqr-code> img src/uploads/logos/demo_qr.png altSafeQRCall 체험용 QR코드 stylewidth: 100%; height: 100%; object-fit: contain; cursor: pointer; onclickwindow.open(https://sqrc.kr/demotest, _blank) title클릭하여 체험하기> /div> p classscan-text>📱 QR 코드 스캔/p> /div> /div> /div> !-- 오른쪽: 프로세스 단계 --> div classprocess-steps data-aosfade-left> div classprocess-step data-aosfade-left data-aos-delay100> div classstep-number>1/div> div classstep-content> h3 classstep-title>!-- CMS에서 로드 -->/h3> p classstep-desc> !-- CMS에서 로드 --> /p> /div> /div> div classarrow-icon> svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 24 24> path dM12 16l-6-6h12l-6 6z/> /svg> /div> div classprocess-step data-aosfade-left data-aos-delay200> div classstep-number>2/div> div classstep-content> h3 classstep-title>!-- CMS에서 로드 -->/h3> p classstep-desc> !-- CMS에서 로드 --> /p> /div> /div> div classarrow-icon> svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 24 24> path dM12 16l-6-6h12l-6 6z/> /svg> /div> div classprocess-step data-aosfade-left data-aos-delay300> div classstep-number>3/div> div classstep-content> h3 classstep-title>!-- CMS에서 로드 -->/h3> p classstep-desc> !-- CMS에서 로드 --> /p> /div> /div> /div> /div> /div> /section> !-- Features 섹션 --> section classsection-features idfeatures roleregion aria-label기능 소개 섹션> div classfeatures-content> !-- 섹션 헤더 --> div classsection-header data-aosfade-up> div classsection-subtitle>Features/div> h2 classsection-title> !-- CMS에서 로드 --> /h2> p classsection-description> !-- CMS에서 로드 --> /p> /div> !-- Features 그리드 --> div classfeatures-grid> !-- Feature 1: 무작위 변경 안심번호 --> div classfeature-card data-aoszoom-in data-aos-delay100> div classfeature-icon>🔄/div> h3 classfeature-title> !-- CMS에서 로드 --> /h3> p classfeature-desc> !-- CMS에서 로드 --> /p> /div> !-- Feature 2: 문자 수신 가능 --> div classfeature-card data-aoszoom-in data-aos-delay200> div classfeature-icon>💬/div> h3 classfeature-title> !-- CMS에서 로드 --> /h3> p classfeature-desc> !-- CMS에서 로드 --> /p> /div> !-- Feature 3: 최대 4개 번호 등록 --> div classfeature-card data-aoszoom-in data-aos-delay300> div classfeature-icon>📱/div> h3 classfeature-title> !-- CMS에서 로드 --> /h3> p classfeature-desc> !-- CMS에서 로드 --> /p> /div> !-- Feature 4: 평생 무료 (특별 배지) --> div classfeature-card data-aoszoom-in data-aos-delay400> span classfeature-badge>평생 무료/span> div classfeature-icon>💰/div> h3 classfeature-title> !-- CMS에서 로드 --> /h3> p classfeature-desc> !-- CMS에서 로드 --> /p> /div> /div> /div> /section> !-- FAQ 섹션 --> section classsection-faq idfaq roleregion aria-label자주 묻는 질문 섹션> div classfaq-content> !-- 섹션 헤더 --> div classsection-header data-aosfade-up> div classsection-subtitle>FAQ/div> h2 classsection-title> !-- CMS에서 로드 --> /h2> p classsection-description> !-- CMS에서 로드 --> /p> /div> !-- FAQ 리스트 --> div classfaq-list> !-- FAQ 1 --> div classfaq-item data-aosfade-up data-aos-delay100> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 2 --> div classfaq-item data-aosfade-up data-aos-delay200> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 3 --> div classfaq-item data-aosfade-up data-aos-delay300> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 4 --> div classfaq-item data-aosfade-up data-aos-delay400> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 5 --> div classfaq-item data-aosfade-up data-aos-delay500> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 6 --> div classfaq-item data-aosfade-up data-aos-delay600> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> !-- FAQ 7 --> div classfaq-item data-aosfade-up data-aos-delay700> button classfaq-question aria-expandedfalse> span classfaq-question-text>!-- CMS에서 로드 -->/span> span classfaq-icon>▼/span> /button> div classfaq-answer> p classfaq-answer-text> !-- CMS에서 로드 --> /p> /div> /div> /div> /div> /section> !-- CTA 섹션 --> section classsection-cta idcta roleregion aria-label구매 안내 섹션> div classcta-content data-aoszoom-in> h2 classcta-title> !-- CMS에서 로드 --> /h2> p classcta-description> !-- CMS에서 로드 --> /p> a hrefhttps://safeqrcall.com/purchase classcta-button> span classcta-button-text>!-- CMS에서 로드 -->/span> /a> /div> /section> !-- Footer --> footer classfooter rolecontentinfo aria-label사이트 정보> div classfooter-content> div classfooter-grid> !-- Footer: 회사 정보 --> div classfooter-section footer-about> div classfooter-logo> img src/uploads/logos/homepage_footer_logo.png altSafeQRCall data-logofooter> /div> p classfooter-description> !-- CMS에서 로드 --> /p> div classfooter-company-info> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>상호명:/strong> span classcompany-name styledisplay: inline-block;>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>대표자:/strong> span classcompany-ceo styledisplay: inline-block;>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>사업자번호:/strong> span classcompany-business-number styledisplay: inline-block;>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>주소:/strong> span classcompany-address styledisplay: inline-block; vertical-align: top; max-width: calc(100% - 140px);>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>이메일:/strong> span classcompany-email styledisplay: inline-block;>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>고객센터:/strong> span classcompany-phone styledisplay: inline-block; vertical-align: top; max-width: calc(100% - 140px); white-space: pre-line;>!-- CMS에서 로드 -->/span> /p> p stylemargin-bottom: 12px;> strong styledisplay: inline-block; min-width: 130px; vertical-align: top;>24시 관제센터:/strong> span classcompany-monitoring styledisplay: inline-block; vertical-align: top; max-width: calc(100% - 140px); white-space: pre-line;>!-- CMS에서 로드 -->/span> /p> /div> /div> !-- Footer: 빠른 링크 --> div classfooter-section> h3 classfooter-section-title onclicktoggleFooterSection(this)> 빠른 링크 span classfooter-accordion-icon>▼/span> /h3> div classfooter-links-wrapper> ul classfooter-links> li>a href/#hero>홈/a>/li> li>a href/#problem>문제점/a>/li> li>a href/#solution>해결책/a>/li> li>a href/#features>기능/a>/li> li>a href/#faq>FAQ/a>/li> /ul> /div> /div> !-- Footer: 법적 고지 --> div classfooter-section> h3 classfooter-section-title onclicktoggleFooterSection(this)> 법적 고지 span classfooter-accordion-icon>▼/span> /h3> div classfooter-links-wrapper> ul classfooter-links> li>a href/terms>이용약관/a>/li> li>a href/privacy>개인정보처리방침/a>/li> /ul> /div> /div> /div> !-- Copyright --> div classfooter-bottom> p classfooter-copyright> !-- CMS에서 로드 --> /p> /div> /div> /footer> !-- AOS Animation Library --> script srchttps://unpkg.com/aos@2.3.1/dist/aos.js>/script> script> // CMS 데이터 로드 및 적용 async function loadHomepageContent() { try { console.log(Homepage CMS Loading content...); // 모든 섹션 데이터 한번에 로드 const sections hero, problem, solution, features, faq, cta, footer; const promises sections.map(section > fetch(`/api/admin/homepage-content/${section}`) .then(res > res.json()) .then(data > ({ section, data })) .catch(err > { console.error(`Homepage CMS Error loading ${section}:`, err); return { section, data: { ok: false } }; }) ); const results await Promise.all(promises); // 각 섹션에 데이터 적용 results.forEach(({ section, data }) > { if (data.ok && data.content && Object.keys(data.content).length > 0) { console.log(`Homepage CMS Applying ${section} content`); applyContentToSection(section, data.content); } else { console.log(`Homepage CMS No content for ${section}, using defaults`); } }); console.log(Homepage CMS Content loaded successfully); // 로고 로드 await loadLogos(); } catch (error) { console.error(Homepage CMS Fatal error:, error); } } // 로고 로드 함수 async function loadLogos() { try { console.log(Homepage Loading logos...); const response await fetch(/api/logos); const data await response.json(); if (data.ok && data.logos && data.logos.homepage) { // Hero 로고: homepage.dark 사용 const heroLogoPath data.logos.homepage.dark; if (heroLogoPath) { const heroLogo document.querySelector(.hero-logo img); if (heroLogo) { heroLogo.src heroLogoPath + ?t + Date.now(); console.log(Homepage Hero logo updated:, heroLogoPath); } // OG Image const ogImage document.querySelector(metapropertyog:image); if (ogImage) { ogImage.content heroLogoPath; console.log(Homepage OG image updated:, heroLogoPath); } } // Footer 로고: homepage.light 사용 (푸터 전용) const footerLogoPath data.logos.homepage.light; if (footerLogoPath) { const footerLogo document.querySelector(.footer-logo img); if (footerLogo) { footerLogo.src footerLogoPath + ?t + Date.now(); console.log(Homepage Footer logo updated:, footerLogoPath); } } } else { console.log(Homepage Logo API returned no data); } } catch (error) { console.error(Homepage Error loading logos:, error); } } // 섹션별 컨텐츠 적용 함수 function applyContentToSection(section, content) { try { if (section hero) { applyHeroContent(content); } else if (section problem) { applyProblemContent(content); } else if (section solution) { applySolutionContent(content); } else if (section features) { applyFeaturesContent(content); } else if (section faq) { applyFaqContent(content); } else if (section cta) { applyCtaContent(content); } else if (section footer) { applyFooterContent(content); } } catch (error) { console.error(`Homepage CMS Error applying ${section}:`, error); } } // Hero 섹션 적용 function applyHeroContent(content) { if (content.title) { const titleEl document.querySelector(.hero-title); if (titleEl) titleEl.innerHTML content.title; } if (content.subtitle_strong || content.subtitle_text) { const subtitleEl document.querySelector(.hero-subtitle); if (subtitleEl) { // 줄바꿈 문자를 br>로 변환 const strongText (content.subtitle_strong || ).replace(/\n/g, br>); const normalText (content.subtitle_text || ).replace(/\n/g, br>); // strong과 normal 사이에 br> 추가 (별도 줄로 표시) if (strongText && normalText) { subtitleEl.innerHTML `strong>${strongText}/strong>br>${normalText}`; } else if (strongText) { subtitleEl.innerHTML `strong>${strongText}/strong>`; } else if (normalText) { subtitleEl.innerHTML normalText; } } } if (content.cta_text) { const ctaBtn document.querySelector(.hero .cta-button); if (ctaBtn) ctaBtn.textContent content.cta_text; } } // Problem 섹션 적용 function applyProblemContent(content) { if (content.title) { const titleEl document.querySelector(#problem .section-title); if (titleEl) titleEl.innerHTML content.title; } // 3개 카드 for (let i 1; i 3; i++) { const card document.querySelector(`#problem .problem-card:nth-child(${i})`); if (card) { if (content`card${i}_icon`) { const icon card.querySelector(.problem-icon); if (icon) icon.textContent content`card${i}_icon`; } if (content`card${i}_title`) { const title card.querySelector(.problem-title); if (title) title.innerHTML content`card${i}_title`; } if (content`card${i}_desc`) { const desc card.querySelector(.problem-desc); if (desc) desc.innerHTML content`card${i}_desc`; } } } if (content.conclusion) { const conclusionEl document.querySelector(#problem .problem-conclusion p); if (conclusionEl) conclusionEl.innerHTML content.conclusion; } } // Solution 섹션 적용 function applySolutionContent(content) { if (content.title) { const titleEl document.querySelector(#solution .section-title); if (titleEl) titleEl.innerHTML content.title; } if (content.desc) { const descEl document.querySelector(#solution .section-description); if (descEl) descEl.innerHTML content.desc; } // 3단계 프로세스 for (let i 1; i 3; i++) { const step document.querySelector(`#solution .process-step:nth-of-type(${i * 2 - 1})`); if (step) { if (content`step${i}_title`) { const title step.querySelector(.step-title); if (title) title.textContent content`step${i}_title`; } if (content`step${i}_desc`) { const desc step.querySelector(.step-desc); if (desc) desc.innerHTML content`step${i}_desc`; } } } } // Features 섹션 적용 function applyFeaturesContent(content) { if (content.title) { const titleEl document.querySelector(#features .section-title); if (titleEl) titleEl.innerHTML content.title; } if (content.desc) { const descEl document.querySelector(#features .section-description); if (descEl) descEl.innerHTML content.desc; } // 4개 기능 카드 for (let i 1; i 4; i++) { const card document.querySelector(`#features .feature-card:nth-child(${i})`); if (card) { if (content`feature${i}_icon`) { const icon card.querySelector(.feature-icon); if (icon) icon.textContent content`feature${i}_icon`; } if (content`feature${i}_title`) { const title card.querySelector(.feature-title); if (title) title.innerHTML content`feature${i}_title`; } if (content`feature${i}_desc`) { const desc card.querySelector(.feature-desc); if (desc) desc.innerHTML content`feature${i}_desc`; } if (i 4 && content.feature4_badge) { let badge card.querySelector(.feature-badge); if (!badge) { badge document.createElement(div); badge.className feature-badge; card.querySelector(.feature-icon).appendChild(badge); } badge.textContent content.feature4_badge; } } } } // FAQ 섹션 적용 function applyFaqContent(content) { if (content.title) { const titleEl document.querySelector(#faq .section-title); if (titleEl) titleEl.innerHTML content.title; } if (content.desc) { const descEl document.querySelector(#faq .section-description); if (descEl) descEl.innerHTML content.desc; } // 7개 FAQ 아이템 for (let i 1; i 7; i++) { const item document.querySelector(`#faq .faq-item:nth-child(${i})`); if (item) { if (content`faq${i}_question`) { const question item.querySelector(.faq-question-text); if (question) question.textContent content`faq${i}_question`; } if (content`faq${i}_answer`) { const answer item.querySelector(.faq-answer); if (answer) answer.innerHTML content`faq${i}_answer`; } } } } // CTA 섹션 적용 function applyCtaContent(content) { if (content.title) { const titleEl document.querySelector(#cta .cta-title); if (titleEl) titleEl.innerHTML content.title; } if (content.desc) { const descEl document.querySelector(#cta .cta-description); if (descEl) descEl.innerHTML content.desc; } if (content.button_text) { const btnEl document.querySelector(#cta .cta-button); if (btnEl) btnEl.textContent content.button_text; } if (content.button_url) { const btnEl document.querySelector(#cta .cta-button); if (btnEl) btnEl.href content.button_url; } } // Footer 섹션 적용 function applyFooterContent(content) { if (content.desc) { const descEl document.querySelector(.footer-description); if (descEl) descEl.innerHTML content.desc; } // 회사 정보 if (content.company_name) { const el document.querySelector(.company-name); if (el) el.textContent content.company_name; } if (content.company_ceo) { const el document.querySelector(.company-ceo); if (el) el.textContent content.company_ceo; } if (content.company_business_number) { const el document.querySelector(.company-business-number); if (el) el.textContent content.company_business_number; } if (content.company_address) { const el document.querySelector(.company-address); if (el) el.textContent content.company_address; } if (content.company_email) { const el document.querySelector(.company-email); if (el) el.textContent content.company_email; } if (content.company_phone) { const el document.querySelector(.company-phone); if (el) el.textContent content.company_phone; } if (content.company_monitoring) { const el document.querySelector(.company-monitoring); if (el) el.textContent content.company_monitoring; } if (content.copyright) { const copyrightEl document.querySelector(.footer-bottom p); if (copyrightEl) copyrightEl.textContent content.copyright; } } // 페이지 로드 완료 후 실행 window.addEventListener(load, function() { // CMS 데이터 로드 (먼저 실행) - 주석: loadCMSContent로 통합 // loadHomepageContent(); // 로딩 오버레이 숨기기 const loadingOverlay document.getElementById(loadingOverlay); if (loadingOverlay) { setTimeout(() > { loadingOverlay.classList.add(hidden); }, 300); } }); // CMS 데이터 로드 및 적용 async function loadCMSContent() { try { // 모든 섹션 데이터 병렬 로드 const hero, problem, solution, features, faq, cta, footer await Promise.all( fetch(/api/homepage/content/hero).then(r > r.json()), fetch(/api/homepage/content/problem).then(r > r.json()), fetch(/api/homepage/content/solution).then(r > r.json()), fetch(/api/homepage/content/features).then(r > r.json()), fetch(/api/homepage/content/faq).then(r > r.json()), fetch(/api/homepage/content/cta).then(r > r.json()), fetch(/api/homepage/content/footer).then(r > r.json()) ); console.log(CMS 데이터 로드 완료:, { hero: hero.ok, problem: problem.ok, solution: solution.ok, features: features.ok, faq: faq.ok, cta: cta.ok, footer: footer.ok }); // Hero 섹션 if (hero.ok && hero.section && hero.section.content) { const h hero.section.content; const heroTitle document.querySelector(.hero-title); const heroSubtitle document.querySelector(.hero-subtitle); const heroCta document.querySelector(.hero-cta); if (heroTitle && h.title) heroTitle.innerHTML h.title; if (heroSubtitle && (h.subtitle_strong || h.subtitle_text)) { heroSubtitle.innerHTML `strong>${h.subtitle_strong || }/strong>br>${h.subtitle_text || }`; } if (heroCta && h.cta_text) heroCta.textContent h.cta_text; console.log(CMS Hero 섹션 적용 완료); } // Problem 섹션 (CMS 배열 구조 사용) if (problem.ok && problem.section && problem.section.content) { const p problem.section.content; const problemTitle document.querySelector(#problem .section-title); if (problemTitle && p.title) problemTitle.innerHTML p.title; // Problem 카드 업데이트 const problemCards document.querySelectorAll(#problem .problem-card); for (let i 0; i problemCards.length; i++) { const card problemCardsi; const num i + 1; const icon card.querySelector(.problem-icon); const title card.querySelector(h3); const desc card.querySelector(p); if (icon && p`card${num}_icon`) icon.textContent p`card${num}_icon`; if (title && p`card${num}_title`) title.innerHTML p`card${num}_title`; if (desc && p`card${num}_desc`) desc.innerHTML p`card${num}_desc`; } // Conclusion 텍스트 업데이트 const conclusionText document.querySelector(#problem .problem-conclusion-text); if (conclusionText && p.conclusion) conclusionText.innerHTML p.conclusion; console.log(CMS Problem 섹션 적용 완료); } // Solution 섹션 if (solution.ok && solution.section && solution.section.content) { const s solution.section.content; console.log(Solution CMS Applying solution data:, s); const solutionTitle document.querySelector(#solution .section-title); const solutionDesc document.querySelector(#solution .section-description); if (solutionTitle && s.title) solutionTitle.innerHTML s.title; if (solutionDesc && s.desc) solutionDesc.innerHTML s.desc; // Process steps 업데이트 (step1, step2, step3) const processSteps document.querySelectorAll(#solution .process-step); for (let i 0; i Math.min(processSteps.length, 3); i++) { const stepNum i + 1; const step processStepsi; const stepTitle step.querySelector(.step-title); const stepDesc step.querySelector(.step-desc); if (stepTitle && s`step${stepNum}_title`) { stepTitle.innerHTML s`step${stepNum}_title`; } if (stepDesc && s`step${stepNum}_desc`) { stepDesc.innerHTML s`step${stepNum}_desc`; } } console.log(Solution CMS Solution data applied successfully); } // Features 섹션 if (features.ok && features.section && features.section.content) { const f features.section.content; // 섹션 제목과 설명 업데이트 const featuresTitle document.querySelector(#features .section-title); const featuresDesc document.querySelector(#features .section-description); if (featuresTitle && f.title) featuresTitle.innerHTML f.title; if (featuresDesc && f.desc) featuresDesc.innerHTML f.desc; // Feature 카드 업데이트 const featureCards document.querySelectorAll(#features .feature-card); for (let i 0; i featureCards.length; i++) { const card featureCardsi; const num i + 1; const icon card.querySelector(.feature-icon); const title card.querySelector(h3); const desc card.querySelector(p); if (icon && f`feature${num}_icon`) icon.textContent f`feature${num}_icon`; if (title && f`feature${num}_title`) title.innerHTML f`feature${num}_title`; if (desc && f`feature${num}_desc`) desc.innerHTML f`feature${num}_desc`; } console.log(CMS Features 섹션 적용 완료); } // FAQ 섹션 if (faq.ok && faq.section && faq.section.content) { const faqData faq.section.content; console.log(FAQ CMS Applying FAQ data:, faqData); const faqTitle document.querySelector(#faq .section-title); const faqDesc document.querySelector(#faq .section-description); if (faqTitle && faqData.title) faqTitle.innerHTML faqData.title; if (faqDesc && faqData.desc) faqDesc.innerHTML faqData.desc; // FAQ 아이템 업데이트 (최대 7개) const faqItems document.querySelectorAll(#faq .faq-item); for (let i 0; i Math.min(faqItems.length, 7); i++) { const faqNum i + 1; const item faqItemsi; const question item.querySelector(.faq-question-text); const answer item.querySelector(.faq-answer-text); if (question && faqData`faq${faqNum}_question`) { question.innerHTML faqData`faq${faqNum}_question`; } if (answer && faqData`faq${faqNum}_answer`) { answer.innerHTML faqData`faq${faqNum}_answer`; } } console.log(FAQ CMS FAQ data applied successfully); } // CTA 섹션 if (cta.ok && cta.section && cta.section.content) { const c cta.section.content; console.log(CTA CMS Applying CTA data:, c); const ctaTitle document.querySelector(#cta .cta-title); const ctaDesc document.querySelector(#cta .cta-description); const ctaButton document.querySelector(#cta .cta-button); const ctaButtonText document.querySelector(#cta .cta-button-text); if (ctaTitle && c.title) ctaTitle.innerHTML c.title; if (ctaDesc && c.desc) ctaDesc.innerHTML c.desc; if (ctaButton && c.button_url) ctaButton.href c.button_url; if (ctaButtonText && c.button_text) ctaButtonText.textContent c.button_text; console.log(CTA CMS CTA data applied successfully); } // Footer 섹션 if (footer.ok && footer.section && footer.section.content) { const ft footer.section.content; console.log(Footer CMS Applying footer data:, ft); // 개별 필드 업데이트 const companyName document.querySelector(.company-name); const companyCeo document.querySelector(.company-ceo); const companyBusinessNumber document.querySelector(.company-business-number); const companyAddress document.querySelector(.company-address); const companyEmail document.querySelector(.company-email); const companyPhone document.querySelector(.company-phone); const companyMonitoring document.querySelector(.company-monitoring); if (companyName && ft.company_name) companyName.textContent ft.company_name; if (companyCeo && ft.company_ceo) companyCeo.textContent ft.company_ceo; if (companyBusinessNumber && ft.company_business_number) companyBusinessNumber.textContent ft.company_business_number; if (companyAddress && ft.company_address) { const formattedAddress ft.company_address.replace(/\n/g, br>); companyAddress.innerHTML formattedAddress; } if (companyEmail && ft.company_email) companyEmail.textContent ft.company_email; if (companyPhone && ft.company_phone) companyPhone.textContent ft.company_phone; if (companyMonitoring && ft.company_monitoring) companyMonitoring.textContent ft.company_monitoring; console.log(Footer CMS Footer data applied successfully); } console.log(✅ CMS 콘텐츠 로드 완료); // 로고 로드 await loadLogos(); } catch (error) { console.error(❌ CMS 콘텐츠 로드 실패:, error); // 에러 발생 시 하드코딩된 내용 유지 } } // 페이지 로드 시 CMS 데이터 로드 if (document.readyState loading) { document.addEventListener(DOMContentLoaded, loadCMSContent); } else { loadCMSContent(); } // Footer 아코디언 토글 function toggleFooterSection(element) { const section element.closest(.footer-section); section.classList.toggle(active); } // AOS 초기화 AOS.init({ duration: 1000, once: true, offset: 100, disable: window.matchMedia((prefers-reduced-motion: reduce)).matches }); // 스크롤 다운 버튼 이벤트 (클릭 + 엔터키) const scrollIndicator document.querySelector(.scroll-indicator); if (scrollIndicator) { const scrollToProblem () > { document.querySelector(#problem).scrollIntoView({ behavior: smooth }); }; scrollIndicator.addEventListener(click, scrollToProblem); scrollIndicator.addEventListener(keydown, function(e) { if (e.key Enter || e.key ) { e.preventDefault(); scrollToProblem(); } }); } // FAQ 아코디언 기능 (접근성 개선) document.querySelectorAll(.faq-question).forEach(button > { button.addEventListener(click, function() { const faqItem this.parentElement; const isActive faqItem.classList.contains(active); // 모든 FAQ 아이템 닫기 및 aria-expanded 업데이트 document.querySelectorAll(.faq-item).forEach(item > { item.classList.remove(active); const btn item.querySelector(.faq-question); if (btn) { btn.setAttribute(aria-expanded, false); } }); // 클릭한 아이템만 열기 (이미 열려있었다면 닫기) if (!isActive) { faqItem.classList.add(active); this.setAttribute(aria-expanded, true); } else { this.setAttribute(aria-expanded, false); } }); }); // 성능 모니터링 (개발용) if (typeof performance ! undefined && performance.timing) { window.addEventListener(load, function() { setTimeout(() > { const loadTime performance.timing.loadEventEnd - performance.timing.navigationStart; console.log(페이지 로드 시간:, loadTime + ms); }, 0); }); } // 비디오 배경 폴백 핸들러 (function initHeroBackground() { const heroVideo document.getElementById(heroVideo); const heroGrid document.getElementById(heroGrid); if (!heroVideo || !heroGrid) { console.warn(Hero 비디오 또는 그리드 요소를 찾을 수 없습니다.); return; } // 비디오 소스가 있는지 확인 const hasVideoSources heroVideo.children.length > 0; if (!hasVideoSources) { // 비디오 소스 없음 - 애니메이션 그리드 사용 heroVideo.style.display none; heroGrid.style.display block; console.log(비디오 소스 없음: 애니메이션 그리드 표시); return; } // 비디오 소스 있음 - 로드 시도 heroVideo.addEventListener(loadeddata, function() { // 비디오 로드 성공 heroGrid.style.display none; heroVideo.style.display block; console.log(비디오 로드 성공: 비디오 배경 표시); }); heroVideo.addEventListener(error, function() { // 비디오 로드 실패 - 그리드로 폴백 heroVideo.style.display none; heroGrid.style.display block; console.warn(비디오 로드 실패: 애니메이션 그리드로 폴백); }); // 비디오 로드 타임아웃 (3초) setTimeout(function() { if (heroVideo.readyState 2) { // HAVE_CURRENT_DATA heroVideo.style.display none; heroGrid.style.display block; console.warn(비디오 로드 타임아웃: 애니메이션 그리드로 폴백); } }, 3000); })(); // 에러 핸들링 window.addEventListener(error, function(e) { console.error(페이지 에러:, e.message); }); /script> /body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]