Files
sam-sales/index.php
2025-12-19 13:12:30 +09:00

1013 lines
56 KiB
PHP

<?php require_once 'session.php'; ?>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CodeBridge-X SAM - 영업관리 </title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'Noto Sans KR', 'sans-serif'],
},
colors: {
brand: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
900: '#0c4a6e',
}
},
animation: {
blob: "blob 7s infinite",
'fade-in-up': 'fadeInUp 0.8s ease-out forwards',
},
keyframes: {
blob: {
"0%": { transform: "translate(0px, 0px) scale(1)" },
"33%": { transform: "translate(30px, -50px) scale(1.1)" },
"66%": { transform: "translate(-20px, 20px) scale(0.9)" },
"100%": { transform: "translate(0px, 0px) scale(1)" },
},
fadeInUp: {
'0%': { opacity: '0', transform: 'translateY(20px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
}
},
}
}
}
</script>
<style>
.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
.animation-delay-2000 { animation-delay: 2s; }
.animation-delay-4000 { animation-delay: 4s; }
/* Hide scrollbar for clean modal */
.no-scroll { overflow: hidden; }
/* Image Zoom & Float Effect */
.img-zoom-container {
overflow: visible !important;
perspective: 1000px;
}
.img-zoom-target {
cursor: zoom-in;
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
position: relative;
z-index: 1;
/* 인라인 스타일을 클래스로 통합 */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
transform: translateZ(0);
backface-visibility: hidden;
}
.img-zoom-target:hover {
transform: scale(1.1) translateZ(0) !important;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
z-index: 50;
}
/* Full Size Viewer */
.img-full-container {
max-height: 70vh;
overflow: auto;
cursor: grab;
background: #f8fafc;
border-radius: 0.75rem;
border: 1px solid #e2e8f0;
}
.img-full-container:active { cursor: grabbing; }
.img-natural {
max-width: none !important;
width: auto !important;
height: auto !important;
}
/* Full Screen Lightbox */
#fullscreen-view {
position: fixed;
inset: 0;
background: rgba(15, 23, 42, 0.95);
z-index: 100;
overflow-y: auto;
display: none;
flex-direction: column;
align-items: center;
padding: 2rem 0; /* 상하 여백 */
}
#fullscreen-view img {
width: 100%; /* 기기 너비 꽉 채움 */
max-width: 1400px; /* PC에서는 너무 커지지 않게 제한 (선택 가능) */
height: auto;
display: block;
box-shadow: 0 0 50px rgba(0,0,0,0.5);
}
.fullscreen-close {
position: fixed;
top: 1.5rem;
right: 1.5rem;
z-index: 110;
background: white;
border-radius: 9999px;
padding: 0.75rem;
cursor: pointer;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
}
/* Mobile touch optimization */
.touch-manipulation {
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}
/* Mobile title optimization - prevent single character line breaks */
@media (max-width: 640px) {
.break-keep {
word-break: keep-all;
overflow-wrap: break-word;
hyphens: none;
}
/* 타이틀 폰트 크기 조정으로 한 글자 줄바꿈 방지 */
h1, h2, h3.title-responsive {
font-size: clamp(1rem, 4vw, 1.5rem);
line-height: 1.3;
}
/* 모바일 버튼 텍스트 줄바꿈 방지 */
button {
word-break: keep-all;
white-space: nowrap;
}
}
</style>
</head>
<body class="bg-slate-50 text-slate-900 font-sans selection:bg-brand-200 selection:text-brand-900">
<!-- Toast Notification -->
<div id="toast" class="fixed top-24 right-4 z-[60] bg-slate-800 text-white px-6 py-4 rounded-xl shadow-2xl flex items-center gap-3 transition-all duration-500 transform translate-x-full opacity-0">
<i data-lucide="check-circle-2" class="text-green-400 w-6 h-6"></i>
<div>
<h4 class="font-bold text-sm">다운로드 시작됨</h4>
<p class="text-slate-400 text-xs">CodeBridgeX_Proposal_v2.4.pdf</p>
</div>
</div>
<!-- Navigation -->
<nav class="sticky top-0 z-30 bg-white/80 backdrop-blur-md border-b border-slate-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center gap-3 cursor-pointer" onclick="filterAssets('All')">
<div class="w-8 h-8 bg-brand-600 rounded-lg flex items-center justify-center text-white font-bold text-lg shadow-lg shadow-brand-200">
S
</div>
<span class="text-xl font-bold tracking-tight text-slate-900">CodeBridgeX <span class="text-brand-600">SAM</span></span>
</div>
<!-- Desktop Navigation -->
<div class="hidden md:flex items-center gap-4">
<a href="sales_scenario/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors">영업 시나리오</a>
<a href="sales_manager_scenario/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors">매니저 시나리오</a>
<a href="salesmanagement/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors">영업관리</a>
<a href="corp/kodata.php" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors">기업분석</a>
<?php if (isset($_SESSION['userid']) && $_SESSION['userid'] != ''): ?>
<div class="flex items-center gap-2 ml-2">
<div class="w-8 h-8 rounded-full bg-slate-200 flex items-center justify-center text-slate-500 font-bold border border-slate-300">
<?= mb_substr($_SESSION['name'], 0, 1) ?>
</div>
<span class="text-sm font-medium text-slate-700"><?= $_SESSION['name'] ?>님</span>
<a href="login/logout.php" class="px-3 py-1.5 bg-slate-100 text-slate-600 text-xs font-bold rounded hover:bg-slate-200 transition-colors border border-slate-200">로그아웃</a>
</div>
<?php else: ?>
<a href="login/login_form.php" class="px-4 py-2 bg-brand-600 text-white text-sm font-bold rounded-lg hover:bg-brand-700 transition-colors shadow-lg shadow-brand-200">
로그인
</a>
<?php endif; ?>
</div>
<!-- Mobile Hamburger Button -->
<button id="mobile-menu-button" class="md:hidden p-2 rounded-lg text-slate-600 hover:bg-slate-100 active:bg-slate-200 transition-colors touch-manipulation">
<i data-lucide="menu" class="w-6 h-6" id="menu-icon"></i>
<i data-lucide="x" class="w-6 h-6 hidden" id="close-icon"></i>
</button>
</div>
<!-- Mobile Menu -->
<div id="mobile-menu" class="hidden md:hidden border-t border-slate-200 py-4">
<div class="flex flex-col gap-3">
<a href="sales_scenario/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors px-2 py-2 hover:bg-slate-50 rounded-lg" onclick="closeMobileMenu()">영업 시나리오</a>
<a href="sales_manager_scenario/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors px-2 py-2 hover:bg-slate-50 rounded-lg" onclick="closeMobileMenu()">매니저 시나리오</a>
<a href="salesmanagement/" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors px-2 py-2 hover:bg-slate-50 rounded-lg" onclick="closeMobileMenu()">영업관리</a>
<a href="corp/kodata.php" class="text-sm font-medium text-slate-600 hover:text-brand-600 transition-colors px-2 py-2 hover:bg-slate-50 rounded-lg" onclick="closeMobileMenu()">기업분석</a>
<?php if (isset($_SESSION['userid']) && $_SESSION['userid'] != ''): ?>
<div class="flex items-center gap-2 px-2 py-2 border-t border-slate-200 mt-2 pt-3">
<div class="w-8 h-8 rounded-full bg-slate-200 flex items-center justify-center text-slate-500 font-bold border border-slate-300">
<?= mb_substr($_SESSION['name'], 0, 1) ?>
</div>
<span class="text-sm font-medium text-slate-700 flex-1"><?= $_SESSION['name'] ?>님</span>
<a href="login/logout.php" class="px-3 py-1.5 bg-slate-100 text-slate-600 text-xs font-bold rounded hover:bg-slate-200 transition-colors border border-slate-200" onclick="closeMobileMenu()">로그아웃</a>
</div>
<?php else: ?>
<a href="login/login_form.php" class="px-4 py-2 bg-brand-600 text-white text-sm font-bold rounded-lg hover:bg-brand-700 transition-colors shadow-lg shadow-brand-200 text-center mt-2" onclick="closeMobileMenu()">
로그인
</a>
<?php endif; ?>
</div>
</div>
</div>
</nav>
<!-- Hero Section -->
<header class="relative bg-white pt-16 pb-20 lg:pt-24 lg:pb-28 overflow-hidden">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div class="text-center max-w-4xl mx-auto">
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-brand-50 text-brand-700 text-xs font-semibold uppercase tracking-wider mb-6 animate-fade-in-up">
<i data-lucide="shield-check" class="w-4 h-4"></i>
CEO Management Solution
</div>
<h1 class="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-extrabold text-slate-900 tracking-tight mb-6 animate-fade-in-up delay-100 leading-tight">
<span class="whitespace-nowrap">직원 관리 도구가 아닙니다.</span><br />
<span class="text-transparent bg-clip-text bg-gradient-to-r from-brand-600 to-indigo-600 whitespace-nowrap">
대표님 경영 무기입니다.
</span>
</h1>
<p class="text-lg sm:text-xl text-slate-500 mb-10 leading-relaxed max-w-2xl mx-auto animate-fade-in-up delay-200">
SAM은 현장에 없어도, 현장을 다 보여줍니다. <br class="hidden sm:block"/>
대표님 손 안의 스마트 경영 계기판, SAM<br />
<strong>오직 CEO를 위한 시크릿 대시보드</strong>를 제안하십시오.
</p>
<!-- Main Hero Image -->
<div class="mt-16 relative z-10 animate-fade-in-up delay-300">
<div class="relative rounded-2xl overflow-hidden shadow-2xl border-4 border-white/50 bg-white">
<img src="img/sam_project.jpg" alt="SAM Project Dashboard" class="w-full h-auto object-cover">
<div class="absolute inset-0 bg-gradient-to-t from-slate-900/10 to-transparent pointer-events-none"></div>
</div>
<!-- Decorative Elements around image -->
<div class="absolute -top-10 -right-10 w-24 h-24 bg-brand-400 rounded-full mix-blend-multiply filter blur-2xl opacity-40 animate-blob"></div>
<div class="absolute -bottom-10 -left-10 w-24 h-24 bg-indigo-400 rounded-full mix-blend-multiply filter blur-2xl opacity-40 animate-blob animation-delay-2000"></div>
</div>
</div>
</div>
<!-- Background Decorations -->
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full z-0 pointer-events-none">
<div class="absolute top-20 left-10 w-72 h-72 bg-brand-200 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-blob"></div>
<div class="absolute top-20 right-10 w-72 h-72 bg-indigo-200 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-blob animation-delay-2000"></div>
<div class="absolute -bottom-8 left-1/2 w-72 h-72 bg-pink-200 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-blob animation-delay-4000"></div>
</div>
</header>
<!-- Main Content -->
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="flex flex-col sm:flex-row items-center justify-between mb-8 gap-4">
<h2 class="text-2xl font-bold text-slate-900">영업 자료</h2>
<div id="filter-buttons" class="flex flex-wrap gap-2 justify-center">
<!-- Filter buttons injected by JS -->
</div>
</div>
<!-- Grid Container -->
<div id="assets-grid" class="grid grid-cols-1 md:grid-cols-3 gap-6 auto-rows-auto">
<!-- Cards injected by JS -->
</div>
<div id="empty-state" class="hidden text-center py-20 text-slate-400 col-span-3">
해당 카테고리에 자료가 없습니다.
</div>
</main>
<!-- Footer -->
<footer class="bg-white border-t border-slate-200 py-12 mt-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center gap-6">
<p class="text-slate-500 text-sm">© 2025 CodeBridge-X Corp. 영업 관리</p>
<div class="flex gap-6">
<a href="#" class="text-slate-400 hover:text-slate-600">사내 전용 (대외비)</a>
<a href="#" class="text-slate-400 hover:text-slate-600">영업 스크립트</a>
<a href="#" class="text-slate-400 hover:text-slate-600">고객 지원</a>
</div>
</div>
</footer>
<!-- Modal Backdrop & Modal -->
<div id="modal-backdrop" class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-50 hidden transition-opacity opacity-0" onclick="closeModal()"></div>
<div id="modal-container" class="fixed inset-0 z-50 flex items-center justify-center p-4 pointer-events-none hidden">
<!-- Modal Content injected by JS -->
</div>
<!-- Full Screen Viewer Overlay -->
<div id="fullscreen-view" onclick="closeFullscreen()">
<div class="fullscreen-close">
<i data-lucide="x" class="w-6 h-6 text-slate-900"></i>
</div>
<img id="fullscreen-img" src="" alt="Full size view" onclick="event.stopPropagation()">
</div>
<!-- PDF Viewer Modal -->
<div id="pdf-modal-backdrop" class="fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-[70] hidden transition-opacity opacity-0" onclick="closePdfViewer()"></div>
<div id="pdf-modal-container" class="fixed inset-0 z-[70] flex items-center justify-center p-4 pointer-events-none hidden">
<div class="bg-white rounded-2xl shadow-2xl w-full max-w-[95vw] h-[95vh] flex flex-col pointer-events-auto scale-95 opacity-0 transition-all duration-300" id="pdf-modal-card">
<div class="sticky top-0 bg-white/90 backdrop-blur-sm p-4 border-b border-slate-100 flex justify-between items-center z-10">
<h3 class="text-lg font-bold text-slate-900" id="pdf-modal-title">상세자료</h3>
<button onclick="closePdfViewer()" class="w-8 h-8 rounded-full bg-slate-50 hover:bg-slate-100 flex items-center justify-center text-slate-500 transition-colors">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="flex-1 overflow-hidden">
<iframe id="pdf-viewer-iframe" src="" class="w-full h-full border-0" frameborder="0"></iframe>
</div>
</div>
</div>
<script>
// 통일된 영업 자료 데이터 구조
// 모든 카드는 동일한 포맷: 이미지(4:3), 설명, 동영상, 오디오, 영업 스크립트
const ASSETS = [
{
id: '1',
title: '대표를 위한 무기',
image: 'img/sales1.jpg',
description: '기존 ERP는 직원의 관리 도구였지만, SAM은 대표님의 의사결정 무기입니다. 직원의 보고를 기다리지 마십시오.',
video: '<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1147875239?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="SAM__CEO를_위한_무기"></iframe></div>',
audio: 'm4a/sales1.m4a',
pdf: 'pdf/sales1.pdf',
script: "대표님, ERP나 MES 들어보셨죠? 보통 직원들이 입력하고 관리하는 도구입니다. 정작 대표님은 직원한테 보고를 받아야만 회사를 알 수 있죠. SAM은 반대입니다. 직원이 아니라 '대표님을 위한 무기'입니다. 외근 중이든 집이든, 대표님 폰에서 회사의 자금, 인력, 리스크가 한눈에 보입니다.",
tags: ['Pitch', 'Opener'],
},
{
id: '2',
title: 'CEO 시크릿 대시보드',
image: 'img/sales2.jpg',
description: 'CEO 시크릿 대시보드는 마치 고성능 전투기의 조종석 대시보드와 같습니다. 수많은 기계적 장치(직원들의 업무)가 뒤에서 복잡하게 돌아가더라도, 조종사(대표님)는 전방의 적기(세무 리스크)와 연료 잔량(자금 흐름) 등 승리를 위해 지금 당장 필요한 정보만 확인하며 최적의 의사결정을 내릴 수 있게 돕기 때문입니다.',
video: '<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1146972515?title=0&amp;byline=0&amp;portrait=0&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="CEO 경영 비서, SAM"></iframe></div>',
audio: 'm4a/sales2.m4a',
pdf: 'pdf/sales2.pdf',
script: "특히 대표님들께서 가장 좋아하시는 기능이 있습니다. 외근 중에 회사에 큰 계약이 성사되거나 매출이 입금되면, 대표님 휴대폰에서만 경쾌하게 'SAM~' 하고 시그니처 알림음이 울립니다. 직원의 보고를 기다릴 필요 없이, 돈이 들어오는 순간을 즉시 느끼며 성취감을 맛보실 수 있습니다.",
tags: ['Demo', 'Dashboard', 'Finance'],
},
{
id: '3',
title: '20가지 고충 해결',
image: 'img/sales3.jpg',
description: '사람(근태), 돈(세금), 운영(현장), 대표의 삶(리스크). CEO가 겪는 20가지 고충을 방어합니다.',
video: '<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1147890755?title=0&amp;byline=0&amp;portrait=0&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="20가지 경영고충"></iframe></div>',
audio: 'm4a/sales3.m4a',
pdf: 'pdf/sales3.pdf',
script: "중소기업 대표님의 머릿속을 20가지로 정리해봤습니다. 직원 근태, 자금 압박, 세무 조사... 이 모든 걸 혼자 감당하고 계시지 않습니까? SAM은 단순 프로그램이 아니라, 이 20가지 리스크를 막아주는 방패입니다.",
tags: ['Pain Points', 'Solution'],
},
{
id: '4',
title: '모바일 & 감성 알림',
image: 'img/sam_alert.jpg',
description: '수주/입금 시 울리는 "SAM~" 알림음. 외근 중에도 회사가 돌아가는 소리를 들으세요.',
video: null,
audio: null,
script: "가장 인기 있는 기능입니다. 외근 나가 계실 때 불안하시죠? 직원이 큰 수주를 따오거나, 거래처에서 돈을 입금하면 대표님 폰에서 'SAM~' 하고 알림이 옵니다. 그 소리만 들으면 '아, 우리 회사 잘 돌아가고 있구나' 안심이 되실 겁니다.",
tags: ['Mobile', 'UX', 'Emotion'],
},
{
id: '6',
title: '영업 전략 해부: CEO에게 파는 법',
image: 'https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80',
description: 'SAM 프로젝트의 핵심 영업 전략은 CEO들의 심리적 약점과 욕구(통제 욕구, 복잡한 것 회피, 비용 민감성)를 파고들어 설득력을 극대화하도록 재정비되었습니다.',
video: '<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1146961422?title=0&amp;byline=0&amp;portrait=0&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="영업_전략_해부__CEO에게_파는_법"></iframe></div>',
audio: null,
script: "1. 통제 욕구 및 불안감 자극/해소: 지각/무단결근 등 특이사항과 내일 나갈 돈(예상 부가세)을 미리 보여주어 통제감을 높여줍니다.\n2. 복잡한 것 회피: 모바일 중심의 '시크릿 모드'와 10초 사용을 강조하여 진입장벽을 낮춥니다.\n3. 비용 민감성: 월 30~50만 원으로 24시간 AI 경영 비서를 고용하는 가성비를 강조합니다.",
tags: ['Strategy', 'CEO Psychology', 'Sales Pitch'],
},
{
id: '7',
title: '자동화 & 인수인계',
image: 'img/sam_time.jpg',
description: '직원이 갑자기 퇴사해도 걱정 없습니다. 견적부터 발주, 출고까지 모든 이력이 클릭 한 번으로 자동 인수인계됩니다.',
video: null,
audio: null,
script: "직원이 갑자기 그만둔다고 하면 눈앞이 캄캄하시죠? 파일 어디 있냐, 거래처 연락처 뭐냐... SAM을 쓰시면 그럴 일 없습니다. 모든 업무 기록이 서버에 남기 때문에, 후임자는 '클릭' 한 번이면 전임자의 모든 업무를 그대로 이어받습니다.",
tags: ['Automation', 'Management'],
},
{
id: '9',
title: '도입 제안 (Closing)',
image: null,
description: '월 구독료로 수천만 원대 맞춤형 ERP 기능과 개인 비서를 고용하는 효과를 누리십시오. 내일부터는 "걱정" 대신 "설렘"으로 출근하십시오.',
video: null,
audio: null,
script: "직원 한 명 월급의 1/10도 안 되는 비용입니다. 이 돈으로 24시간 비서, 그리고 완벽한 경영 시스템을 고용하시는 겁니다. 오늘 결정하시고, 내일부터는 가벼운 마음으로 출근하십시오.",
tags: ['Closing', 'Pricing'],
},
{
id: '10',
title: '[Core Features] 대표님이 반할 기능 8선',
image: null,
description: 'AI 경영 비서부터 자금/세무 관리까지, SAM이 제공하는 8가지 핵심 기능을 3분 요약으로 들어보세요.',
video: null,
audio: 'm4a/strategy.m4a',
script: "AI 경영 비서: 음성 인식 업무일지, 회의록, 자동 번역\n스마트 현장: 사진 토큰 관리, GPS 기반 출퇴근, QR 설비 관리\n자금/세무: 예상 부가세, 법인카드 한도 관리, 경리일보 자동화\n리스크 방어: 미수금 알림, 재고 부족 경고, 신규 거래처 신용 등급 표시\n편의 기능: 용량 걱정 없는 무제한 파일함, 시그니처 매출 알림음",
tags: ['Podcast', 'Audio', 'Feature'],
},
{
id: '11',
title: '1. 대표님의 고민 (Pain Points)',
image: null,
description: '매출은 느는데 이익은 제자리? 직원과 현장을 100% 믿을 수 있나? 세금 낼 때마다 자금 계획이 꼬이나? 이는 정보 부재에서 오는 "전략적 리스크"입니다.',
video: null,
audio: null,
script: "매출은 계속 오르는데, 왜 통장에 남는 돈은 없을까요? 직원들은 정말 열심히 하고 있는 걸까요? 세금 낼 때마다 목돈 마련하느라 허덕이시진 않나요? 더 많은 보고서가 아니라, 대표님 손안에 '진짜 정보'가 필요할 때입니다.",
tags: ['Pain Points', 'Risk', 'Needs'],
},
{
id: '12',
title: '2. 새로운 해법 (Solution)',
image: null,
description: 'SAM은 "실무자 관리 도구"가 아닌 "CEO 의사결정 도구"입니다. 복잡한 입력은 AI가, 대표님은 직관적인 신호등과 요약 카드만 확인하십시오.',
video: null,
audio: null,
script: "기존 ERP는 관리자용이라 복잡하고 비쌉니다. SAM은 다릅니다. 오직 대표님을 위해 설계되었습니다. 복잡한 표 대신 신호등으로, PC 대신 모바일로, 수천만 원 구축비 대신 합리적 구독료로 제공합니다. 복잡한 건 AI에게 맡기고, 대표님은 흐름만 보십시오.",
tags: ['Solution', 'Differentiation', 'AI'],
},
{
id: '13',
title: '3. 핵심 기능 (Core Features)',
image: null,
description: '리스크 사전 방지(미수금, 재고), 자금 흐름 관리(예상 부가세, 한도 체크), 실시간 현장 통제(지각, AI 업무일지).',
video: null,
audio: null,
script: "A업체 미수금 3개월 경과, 접대비 한도 80% 소진, 오늘 지각자 3명... 대표님이 놓치기 쉬운 '리스크'만 골라서 붉은색 알림을 띄워드립니다. 사무실 밖에서도 현장과 자금이 한눈에 들어옵니다.",
tags: ['Features', 'Risk', 'Finance', 'Ops'],
},
{
id: '14',
title: '4. 도입 효과 (ROI)',
image: null,
description: '보고 시간 0분(실시간 확인), 단순 업무 80% 자동화, 의사결정 속도 즉시. 눈에 보이는 비용 절감과 경쟁력 강화를 경험하십시오.',
video: null,
audio: null,
script: "직원이 보고서 만들어서 결재 올릴 때까지 기다리지 마십시오. SAM을 쓰면 보고 시간이 '0분'이 됩니다. 단순 반복 업무는 80% 자동화됩니다. 이게 바로 돈 버는 시스템입니다.",
tags: ['ROI', 'Efficiency', 'Automation'],
},
{
id: '15',
title: '5. 제안 (Investment)',
image: null,
description: '연 3,000만 원 경리 직원 채용 vs 월 30만 원 AI 비서. 24시간 잠들지 않는 AI를 신입사원 월급의 1/10도 안 되는 비용으로 고용하십시오.',
video: null,
audio: null,
script: "사람 한 명 뽑으려면 3천만 원 듭니다. SAM은 월 30만 원입니다. 1/100 비용으로 24시간 잠들지 않고 실수도 없는 완벽한 AI 비서를 채용하시는 겁니다. 이건 지출이 아니라 가장 확실한 투자입니다.",
tags: ['Investment', 'Cost', 'Value'],
},
{
id: '16',
title: '6. 다음 단계 (Next Steps)',
image: null,
description: '백 번 설명보다 한 번의 경험이 낫습니다. 대표님 업종에 맞춘 "무료 진단 & 시연"과 "3일 무료 체험"을 신청하십시오.',
video: null,
audio: null,
script: "우리 회사에 맞을까 고민하지 마세요. 대표님 업종에 딱 맞춘 대시보드를 미리 구성해서 보여드립니다. 3일만 직접 써보시면, 왜 SAM이 필수인지 바로 아실 겁니다.",
tags: ['Call to Action', 'Demo', 'Free Trial'],
}
];
// Constants
const FILTERS = ['전체', 'CEO 설득', '데모'];
let activeFilter = '전체';
// DOM Elements
const gridEl = document.getElementById('assets-grid');
const filterContainer = document.getElementById('filter-buttons');
const emptyState = document.getElementById('empty-state');
const modalBackdrop = document.getElementById('modal-backdrop');
const modalContainer = document.getElementById('modal-container');
const toast = document.getElementById('toast');
// Initial Render
function init() {
renderFilters();
renderGrid();
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
}
// Filter Logic
function renderFilters() {
filterContainer.innerHTML = FILTERS.map(filter => `
<button
onclick="filterAssets('${filter}')"
class="px-3 sm:px-4 py-2 rounded-lg text-xs sm:text-sm font-medium transition-colors duration-200 whitespace-nowrap ${activeFilter === filter ? 'bg-slate-900 text-white shadow-md' : 'bg-white text-slate-600 hover:bg-slate-100 border border-transparent hover:border-slate-200'}"
>
${filter}
</button>
`).join('');
}
window.filterAssets = (filter) => {
activeFilter = filter;
renderFilters();
renderGrid();
lucide.createIcons();
};
function getFilteredAssets() {
if (activeFilter === '전체') return ASSETS;
return ASSETS.filter(asset => {
if (activeFilter === 'CEO 설득') return asset.tags.some(tag => ['Pitch', 'Opener', 'Pain Points', 'Solution', 'Closing', 'Risk', 'Needs', 'Differentiation', 'Investment', 'Cost', 'Value'].includes(tag));
if (activeFilter === '데모') return asset.tags.some(tag => ['Demo', 'Dashboard', 'Video', 'Mobile', 'UX', 'Infra', 'Feature', 'Automation', 'Management'].includes(tag));
return true;
});
}
// Grid Render
function renderGrid() {
const assets = getFilteredAssets();
if (assets.length === 0) {
emptyState.classList.remove('hidden');
} else {
emptyState.classList.add('hidden');
}
gridEl.innerHTML = assets.map(asset => {
// [1] 이미지 영역 (실제 이미지 비율 계산)
let imageHtml = '';
if (asset.image) {
imageHtml = `
<div class="relative bg-slate-50 overflow-hidden group/img cursor-pointer border-b border-slate-100" onclick="openModal('${asset.id}')" data-asset-id="${asset.id}">
<img src="${asset.image}" alt="${asset.title}"
class="w-full h-auto object-cover transform group-hover/img:scale-105 transition-transform duration-700"
style="image-rendering: -webkit-optimize-contrast;"
onload="setImageAspectRatio(this)"
data-asset-id="${asset.id}">
<div class="absolute inset-0 bg-black/5 opacity-0 group-hover/img:opacity-100 transition-opacity flex items-center justify-center pointer-events-none">
<div class="bg-white/90 backdrop-blur p-2 rounded-full shadow-lg">
<i data-lucide="zoom-in" class="w-5 h-5 text-slate-700"></i>
</div>
</div>
</div>`;
} else {
// 이미지가 없을 때 아이콘 표시
let iconName = 'file-text';
if (asset.video) iconName = 'play-circle';
else if (asset.audio) iconName = 'mic';
imageHtml = `
<div class="relative aspect-[4/3] bg-gradient-to-br from-slate-100 to-slate-200 flex items-center justify-center border-b border-slate-100">
<div class="text-slate-300">
<i data-lucide="${iconName}" class="w-16 h-16 opacity-40"></i>
</div>
</div>`;
}
// [2] 정보 영역
return `
<div class="bg-white rounded-2xl border border-slate-200 shadow-sm hover:shadow-xl transition-all duration-500 overflow-hidden flex flex-col group h-full" onclick="openModal('${asset.id}')">
${imageHtml}
<div class="p-6 flex-grow flex flex-col">
<div class="flex items-center justify-between mb-3">
<div class="flex gap-2">
${asset.tags.map(tag => `<span class="text-slate-400 text-[10px] font-medium">#${tag}</span>`).join(' ')}
</div>
<button class="text-slate-300 hover:text-brand-500 transition-colors">
<i data-lucide="share-2" class="w-4 h-4"></i>
</button>
</div>
<h3 class="text-base sm:text-lg font-bold text-slate-900 mb-2 group-hover:text-brand-600 transition-colors break-keep leading-tight" style="word-break: keep-all; overflow-wrap: break-word;">${asset.title}</h3>
<div class="flex-grow">
<p class="text-slate-600 text-sm leading-relaxed mb-4 line-clamp-3">
${asset.description || ''}
</p>
</div>
<!-- 미디어 타입 표시 -->
<div class="mb-3 flex items-center gap-2 text-xs text-slate-400">
${asset.image ? '<span class="flex items-center gap-1"><i data-lucide="image" class="w-3 h-3"></i> 이미지</span>' : ''}
${asset.video ? '<span class="flex items-center gap-1"><i data-lucide="play-circle" class="w-3 h-3"></i> 동영상</span>' : ''}
${asset.audio ? '<span class="flex items-center gap-1"><i data-lucide="mic" class="w-3 h-3"></i> 팟캐스트</span>' : ''}
${asset.script ? '<span class="flex items-center gap-1"><i data-lucide="message-square" class="w-3 h-3"></i> 스크립트</span>' : ''}
</div>
<div class="mt-auto pt-4 border-t border-slate-50 flex items-center justify-between">
<button class="text-brand-600 text-xs font-bold hover:underline flex items-center gap-1">
상세 보기 <i data-lucide="chevron-right" class="w-3 h-3"></i>
</button>
<span class="text-[10px] text-slate-300 font-bold uppercase tracking-widest">SAM</span>
</div>
</div>
</div>
`;
}).join('');
}
// Modal Logic
window.openModal = (id) => {
const asset = ASSETS.find(a => a.id === id);
if (!asset) return;
// Generate content
const tagsHtml = asset.tags.map(tag => `<span class="px-2 py-1 rounded-md bg-slate-100 text-slate-500 text-xs font-medium">#${tag}</span>`).join('');
// 통일된 미디어 표시 구조
let mediaHtml = '';
// 1. 이미지 (실제 비율 계산)
if (asset.image) {
mediaHtml += `
<div class="mb-6">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-5 rounded-full bg-brand-500"></div>
<h4 class="font-bold text-slate-900">이미지</h4>
</div>
<div class="relative group viewer bg-slate-50 rounded-xl overflow-hidden border border-slate-100">
<div class="absolute top-3 right-3 z-[60] flex gap-2 translate-y-2 opacity-0 group-hover:opacity-100 transition-all duration-300">
<button onclick="toggleNaturalSize(this)"
class="px-4 py-2 bg-white/95 backdrop-blur-md shadow-lg border border-slate-200 rounded-full text-xs font-bold text-brand-600 hover:bg-brand-600 hover:text-white transition-all flex items-center gap-2">
<i data-lucide="maximize" class="w-3.5 h-3.5"></i>
<span>원본 크기 보기</span>
</button>
</div>
<div class="img-full-container custom-scrollbar scroll-smooth w-full overflow-hidden">
<img src="${asset.image}"
id="modal-main-img-${asset.id}"
class="w-full h-auto object-contain rounded-xl img-zoom-target"
style="image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges;"
onload="setModalImageAspectRatio(this)">
</div>
</div>
</div>`;
}
// 2. 설명 (이미지 밑에 표시)
if (asset.description) {
mediaHtml += `
<div class="mb-6">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-5 rounded-full bg-brand-500"></div>
<h4 class="font-bold text-slate-900">설명</h4>
</div>
<div class="p-4 bg-slate-50 rounded-xl border border-slate-100 text-slate-700 leading-relaxed">
${asset.description}
</div>
</div>`;
}
// 2. 동영상
if (asset.video) {
mediaHtml += `
<div class="mb-6">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-5 rounded-full bg-brand-500"></div>
<h4 class="font-bold text-slate-900">동영상</h4>
</div>
<div class="aspect-video bg-slate-100 rounded-xl overflow-hidden relative z-0">
${asset.video}
</div>
</div>`;
}
// 3. 오디오 팟캐스트
if (asset.audio) {
mediaHtml += `
<div class="mb-6">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-5 rounded-full bg-brand-500"></div>
<h4 class="font-bold text-slate-900">팟캐스트</h4>
</div>
<div class="bg-slate-900 rounded-xl p-8 text-center">
<div class="w-24 h-24 rounded-full bg-indigo-500 mx-auto mb-6 flex items-center justify-center shadow-lg">
<i data-lucide="mic" class="w-10 h-10 text-white"></i>
</div>
<h4 class="text-white font-bold text-xl mb-2">${asset.title}</h4>
<p class="text-slate-400 text-sm mb-6">SAM Strategy Podcast</p>
<audio controls class="w-full">
<source src="${asset.audio}" type="audio/mp4">
<source src="${asset.audio}" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
</div>`;
}
const modalContent = `
<div class="bg-white rounded-2xl shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto pointer-events-auto scale-95 opacity-0 transition-all duration-300" id="modal-card">
<div class="sticky top-0 bg-white/90 backdrop-blur-sm p-4 border-b border-slate-100 flex justify-between items-center z-10">
<div class="flex items-center gap-2">
<h3 class="text-base sm:text-lg font-bold text-slate-900 break-keep leading-tight" style="word-break: keep-all; overflow-wrap: break-word;">${asset.title}</h3>
</div>
<button onclick="closeModal()" class="w-8 h-8 rounded-full bg-slate-50 hover:bg-slate-100 flex items-center justify-center text-slate-500 transition-colors">
<i data-lucide="x" class="w-5 h-5"></i>
</button>
</div>
<div class="p-6 sm:p-8">
${mediaHtml}
<!-- 영업 스크립트 -->
${asset.script ? `
<div class="mb-8">
<div class="flex items-center gap-2 mb-3">
<div class="w-1 h-5 rounded-full bg-brand-500"></div>
<h4 class="font-bold text-slate-900">영업 스크립트</h4>
</div>
<div class="bg-indigo-50/50 p-5 rounded-xl border border-indigo-100 relative">
<i data-lucide="quote" class="w-5 h-5 text-indigo-200 absolute top-4 left-4"></i>
<p class="text-slate-800 leading-relaxed pl-6 relative z-10 font-medium whitespace-pre-line">"${asset.script}"</p>
</div>
</div>
` : ''}
<div class="flex flex-wrap gap-2 pt-6 border-t border-slate-100">
${tagsHtml}
</div>
</div>
<div class="p-4 border-t border-slate-100 bg-slate-50 rounded-b-2xl flex justify-end gap-3">
<button onclick="closeModal()" class="px-3 sm:px-4 py-2 rounded-lg bg-white border border-slate-200 text-slate-700 font-medium hover:bg-slate-50 transition-colors whitespace-nowrap text-sm sm:text-base">닫기</button>
${asset.pdf ? `
<button onclick="openPdfViewer('${asset.id}')" class="px-3 sm:px-4 py-2 rounded-lg bg-brand-600 text-white font-medium hover:bg-brand-700 shadow-md transition-colors flex items-center gap-2 whitespace-nowrap text-sm sm:text-base">
<i data-lucide="file-text" class="w-4 h-4 flex-shrink-0"></i>
<span>상세자료 보기</span>
</button>
` : `
<button onclick="showDownloadToast(); closeModal()" class="px-3 sm:px-4 py-2 rounded-lg bg-brand-600 text-white font-medium hover:bg-brand-700 shadow-md transition-colors flex items-center gap-2 whitespace-nowrap text-sm sm:text-base">
<i data-lucide="download" class="w-4 h-4 flex-shrink-0"></i>
<span>자료 사용하기</span>
</button>
`}
</div>
</div>
`;
modalContainer.innerHTML = modalContent;
// Animation In
modalBackdrop.classList.remove('hidden');
modalContainer.classList.remove('hidden');
document.body.classList.add('no-scroll');
// Trigger reflow
void modalBackdrop.offsetWidth;
modalBackdrop.classList.remove('opacity-0');
const card = document.getElementById('modal-card');
card.classList.remove('scale-95', 'opacity-0');
lucide.createIcons();
};
window.closeModal = () => {
const card = document.getElementById('modal-card');
if (card) {
card.classList.add('scale-95', 'opacity-0');
}
modalBackdrop.classList.add('opacity-0');
setTimeout(() => {
modalBackdrop.classList.add('hidden');
modalContainer.classList.add('hidden');
document.body.classList.remove('no-scroll');
modalContainer.innerHTML = '';
}, 300);
};
// Toggle Image Natural Size (Now Full Screen Wide View)
window.toggleNaturalSize = (btn) => {
// 버튼의 부모 컨테이너에서 이미지 찾기
const container = btn.closest('.group.viewer') || btn.closest('.relative');
const img = container ? container.querySelector('img.img-zoom-target') : null;
if (!img) {
console.error('이미지를 찾을 수 없습니다.');
return;
}
const fsView = document.getElementById('fullscreen-view');
const fsImg = document.getElementById('fullscreen-img');
if (!fsView || !fsImg) {
console.error('풀스크린 뷰어를 찾을 수 없습니다.');
return;
}
fsImg.src = img.src;
fsView.style.display = 'flex';
document.body.classList.add('no-scroll');
lucide.createIcons();
};
window.closeFullscreen = () => {
const fsView = document.getElementById('fullscreen-view');
fsView.style.display = 'none';
// 모달이 열려있는 상태면 스크롤 제한 유지, 아니면 해제
if (document.getElementById('modal-backdrop').classList.contains('hidden')) {
document.body.classList.remove('no-scroll');
}
};
// PDF Viewer Functions
window.openPdfViewer = (id) => {
const asset = ASSETS.find(a => a.id === id);
if (!asset || !asset.pdf) return;
const pdfBackdrop = document.getElementById('pdf-modal-backdrop');
const pdfContainer = document.getElementById('pdf-modal-container');
const pdfCard = document.getElementById('pdf-modal-card');
const pdfIframe = document.getElementById('pdf-viewer-iframe');
const pdfTitle = document.getElementById('pdf-modal-title');
pdfTitle.textContent = asset.title;
// PDF를 Google Drive Viewer로 표시 (로컬 파일도 가능)
// 또는 직접 PDF 파일 경로 사용 (브라우저 지원 시)
const pdfUrl = asset.pdf;
pdfIframe.src = pdfUrl;
// Animation In
pdfBackdrop.classList.remove('hidden');
pdfContainer.classList.remove('hidden');
document.body.classList.add('no-scroll');
// Trigger reflow
void pdfBackdrop.offsetWidth;
pdfBackdrop.classList.remove('opacity-0');
pdfCard.classList.remove('scale-95', 'opacity-0');
lucide.createIcons();
};
window.closePdfViewer = () => {
const pdfBackdrop = document.getElementById('pdf-modal-backdrop');
const pdfContainer = document.getElementById('pdf-modal-container');
const pdfCard = document.getElementById('pdf-modal-card');
const pdfIframe = document.getElementById('pdf-viewer-iframe');
if (pdfCard) {
pdfCard.classList.add('scale-95', 'opacity-0');
}
pdfBackdrop.classList.add('opacity-0');
setTimeout(() => {
pdfBackdrop.classList.add('hidden');
pdfContainer.classList.add('hidden');
pdfIframe.src = '';
// 모달이 열려있는 상태면 스크롤 제한 유지, 아니면 해제
if (document.getElementById('modal-backdrop').classList.contains('hidden')) {
document.body.classList.remove('no-scroll');
}
}, 300);
};
// 카드 이미지 비율 계산 함수
window.setImageAspectRatio = (img) => {
if (img.naturalWidth && img.naturalHeight) {
const container = img.closest('[data-asset-id]');
if (container) {
container.style.aspectRatio = `${img.naturalWidth} / ${img.naturalHeight}`;
}
}
};
// 모달 이미지 비율 계산 함수
window.setModalImageAspectRatio = (img) => {
if (img.naturalWidth && img.naturalHeight) {
const container = img.closest('.img-full-container');
if (container) {
// 모달에서는 최대 높이 제한을 두고 비율 유지
const maxHeight = window.innerHeight * 0.6;
const aspectRatio = img.naturalWidth / img.naturalHeight;
const calculatedWidth = maxHeight * aspectRatio;
if (calculatedWidth > container.offsetWidth) {
img.style.width = '100%';
img.style.height = 'auto';
} else {
img.style.width = `${calculatedWidth}px`;
img.style.height = `${maxHeight}px`;
}
}
}
};
// Mobile Menu Functions
window.toggleMobileMenu = (e) => {
if (e) {
e.preventDefault();
e.stopPropagation();
}
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
const closeIcon = document.getElementById('close-icon');
if (!mobileMenu || !menuIcon || !closeIcon) {
console.error('Mobile menu elements not found');
return;
}
if (mobileMenu.classList.contains('hidden')) {
mobileMenu.classList.remove('hidden');
menuIcon.classList.add('hidden');
closeIcon.classList.remove('hidden');
} else {
mobileMenu.classList.add('hidden');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
}
// 아이콘 재생성
if (typeof lucide !== 'undefined') {
lucide.createIcons();
}
};
window.closeMobileMenu = () => {
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
const closeIcon = document.getElementById('close-icon');
if (mobileMenu && !mobileMenu.classList.contains('hidden')) {
mobileMenu.classList.add('hidden');
if (menuIcon) menuIcon.classList.remove('hidden');
if (closeIcon) closeIcon.classList.add('hidden');
}
};
// Mobile menu button event listeners
// 스크립트가 body 끝에 있으므로 DOM은 이미 로드됨
(function setupMobileMenuButton() {
const mobileMenuButton = document.getElementById('mobile-menu-button');
if (mobileMenuButton) {
// 터치 이벤트와 클릭 이벤트 모두 처리
let touchStartTime = 0;
mobileMenuButton.addEventListener('touchstart', (e) => {
touchStartTime = Date.now();
e.stopPropagation();
}, { passive: true });
mobileMenuButton.addEventListener('touchend', (e) => {
e.preventDefault();
e.stopPropagation();
// 빠른 터치만 처리 (300ms 이내)
if (Date.now() - touchStartTime < 300) {
toggleMobileMenu(e);
}
}, { passive: false });
mobileMenuButton.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
toggleMobileMenu(e);
});
}
})();
// Close mobile menu when clicking outside
document.addEventListener('click', (e) => {
const mobileMenu = document.getElementById('mobile-menu');
const mobileMenuButton = document.getElementById('mobile-menu-button');
if (mobileMenu && mobileMenuButton &&
!mobileMenu.classList.contains('hidden') &&
!mobileMenu.contains(e.target) &&
!mobileMenuButton.contains(e.target)) {
closeMobileMenu();
}
});
// Close mobile menu on touch outside (for mobile)
document.addEventListener('touchstart', (e) => {
const mobileMenu = document.getElementById('mobile-menu');
const mobileMenuButton = document.getElementById('mobile-menu-button');
if (mobileMenu && mobileMenuButton &&
!mobileMenu.classList.contains('hidden') &&
!mobileMenu.contains(e.target) &&
!mobileMenuButton.contains(e.target)) {
closeMobileMenu();
}
});
// Initialize
init();
</script>
<script src="https://player.vimeo.com/api/player.js"></script>
</body>
</html>