jun0-ds
deploy: HF Spaces 배포
2e03d75
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>💜 하트로그 HeartLog</title>
<style>
/* ── Reset & Base ──────────────────────────── */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Pretendard', 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
}
body {
background: #fff;
color: #1a1a1a;
line-height: 1.7;
overflow-x: hidden;
}
a {
color: #7c3aed;
text-decoration: none;
transition: all 0.2s ease;
}
a:hover {
color: #ec4899;
}
/* ── Gradient System ──────────────────────── */
.gradient-text {
background: linear-gradient(135deg, #7c3aed 0%, #ec4899 50%, #f97316 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.gradient-bg {
background: linear-gradient(135deg, #7c3aed 0%, #ec4899 50%, #f97316 100%);
}
.gradient-bg-soft {
background: linear-gradient(135deg, #f3f0ff 0%, #fdf2f8 50%, #fff7ed 100%);
}
/* ── Layout ───────────────────────────────── */
#main {
max-width: 960px;
margin: 0 auto;
padding: 80px 24px 160px;
}
section {
margin-bottom: 80px;
}
.section-title {
font-size: 28px;
font-weight: 700;
margin-bottom: 24px;
text-align: center;
}
.text-center { text-align: center; }
.text-muted { color: #6b7280; }
/* ── Hero ─────────────────────────────────── */
#hero {
text-align: center;
padding: 60px 0 40px;
}
#hero .logo-emoji {
font-size: 72px;
margin-bottom: 16px;
display: block;
}
#hero h1 {
font-size: 56px;
font-weight: 800;
line-height: 1.2;
margin-bottom: 8px;
}
#hero .subtitle {
font-size: 18px;
font-weight: 500;
color: #6b7280;
margin-bottom: 32px;
}
#hero .tagline {
font-size: 22px;
font-weight: 600;
margin-bottom: 40px;
}
/* ── Link Buttons ─────────────────────────── */
#links {
display: flex;
justify-content: center;
gap: 12px;
flex-wrap: wrap;
margin-bottom: 48px;
}
#links a {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 10px 24px;
color: #fff;
font-size: 15px;
font-weight: 600;
border-radius: 50px;
box-shadow: 0 0 4px rgba(0,0,0,0.3);
transition: all 0.2s ease;
}
#links a:hover {
transform: scale(1.05);
box-shadow: 0 0 8px rgba(0,0,0,0.4);
color: #fff;
}
#links a .icon { font-size: 18px; }
/* ── TL;DR Block ──────────────────────────── */
#tldr {
border-radius: 16px;
padding: 32px;
margin-bottom: 64px;
text-align: center;
}
#tldr .label {
font-size: 14px;
font-weight: 700;
color: #7c3aed;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 12px;
}
#tldr p {
font-size: 18px;
font-weight: 500;
color: #3f3f3f;
line-height: 1.8;
}
/* ── Flow Diagram ─────────────────────────── */
.flow {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 8px;
margin: 32px 0;
}
.flow-step {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 20px;
background: #fff;
border-radius: 16px;
box-shadow: 0 0 6px rgba(0,0,0,0.12);
font-size: 15px;
font-weight: 600;
transition: all 0.2s ease;
}
.flow-step:hover {
transform: scale(1.02);
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
.flow-step .step-emoji { font-size: 24px; }
.flow-arrow {
font-size: 20px;
color: #c4b5fd;
font-weight: 700;
}
/* ── Cards ────────────────────────────────── */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 20px;
margin-top: 24px;
}
.card {
padding: 24px;
border-radius: 16px;
box-shadow: 0 0 6px rgba(0,0,0,0.12);
background: #fff;
transition: all 0.2s ease;
}
.card:hover {
transform: scale(1.02);
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
.card .card-emoji { font-size: 32px; margin-bottom: 12px; }
.card h3 { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.card p { font-size: 14px; color: #4b5563; line-height: 1.6; }
/* ── Type Cards ───────────────────────────── */
.type-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 16px;
margin-top: 24px;
}
.type-card {
text-align: center;
padding: 24px 16px;
border-radius: 16px;
background: #fff;
box-shadow: 0 0 6px rgba(0,0,0,0.12);
transition: all 0.2s ease;
}
.type-card:hover {
transform: scale(1.04);
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
.type-card .type-emoji { font-size: 40px; display: block; margin-bottom: 8px; }
.type-card .type-name { font-size: 16px; font-weight: 700; }
.type-card .type-desc { font-size: 12px; color: #6b7280; margin-top: 4px; }
/* ── Scenario Table ────────────────────────── */
.scenario-section { margin-top: 32px; }
.scenario-section h3 {
font-size: 18px;
font-weight: 700;
margin-bottom: 12px;
}
.scenario-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
}
.scenario-item {
padding: 16px;
border-radius: 12px;
border-left: 4px solid;
background: #fafafa;
transition: all 0.2s ease;
}
.scenario-item:hover {
background: #f3f0ff;
}
.scenario-item.positive { border-color: #ec4899; }
.scenario-item.negative { border-color: #7c3aed; }
.scenario-item.wildcard { border-color: #f97316; }
.scenario-item .scenario-name { font-size: 14px; font-weight: 700; }
.scenario-item .scenario-desc { font-size: 12px; color: #6b7280; margin-top: 2px; }
.scenario-item .scenario-axes { font-size: 11px; color: #a78bfa; margin-top: 4px; }
/* ── Architecture Block ────────────────────── */
.arch-table {
width: 100%;
border-collapse: separate;
border-spacing: 0 8px;
margin-top: 24px;
}
.arch-table td {
padding: 16px 20px;
background: #fff;
font-size: 15px;
vertical-align: middle;
}
.arch-table td:first-child {
border-radius: 12px 0 0 12px;
font-weight: 700;
width: 160px;
color: #7c3aed;
}
.arch-table td:last-child {
border-radius: 0 12px 12px 0;
color: #4b5563;
}
.arch-table tr {
box-shadow: 0 0 4px rgba(0,0,0,0.08);
border-radius: 12px;
}
/* ── Event Structure ──────────────────────── */
.event-flow {
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
margin: 32px 0;
}
.event-step {
width: 100%;
max-width: 500px;
padding: 18px 24px;
border-radius: 12px;
background: #fff;
box-shadow: 0 0 4px rgba(0,0,0,0.1);
font-size: 15px;
text-align: center;
}
.event-step strong { color: #7c3aed; }
.event-arrow {
font-size: 18px;
color: #d8b4fe;
padding: 4px 0;
}
/* ── Diff Comparison ──────────────────────── */
.diff-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin-top: 24px;
}
.diff-card {
padding: 24px;
border-radius: 16px;
text-align: center;
}
.diff-card h4 { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.diff-card p { font-size: 13px; line-height: 1.6; }
.diff-card.old {
background: #f3f4f6;
color: #6b7280;
}
.diff-card.ours {
background: linear-gradient(135deg, #f3f0ff 0%, #fdf2f8 100%);
box-shadow: 0 0 8px rgba(124,58,237,0.15);
}
.diff-card.ours h4 { color: #7c3aed; }
/* ── Team ─────────────────────────────────── */
.team-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
margin-top: 24px;
}
.team-card {
text-align: center;
padding: 24px 16px;
border-radius: 16px;
background: #fff;
box-shadow: 0 0 4px rgba(0,0,0,0.08);
}
.team-card .role {
display: inline-block;
padding: 2px 10px;
border-radius: 50px;
font-size: 11px;
font-weight: 600;
color: #fff;
margin-bottom: 8px;
}
.team-card .name { font-size: 16px; font-weight: 700; }
.team-card .desc { font-size: 12px; color: #6b7280; margin-top: 4px; }
/* ── Bottom Bar ───────────────────────────── */
#bottombar {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
gap: 24px;
color: rgba(255,255,255,0.8);
font-size: 13px;
font-weight: 500;
z-index: 100;
}
#bottombar a {
color: rgba(255,255,255,0.8);
transition: color 0.2s ease;
}
#bottombar a:hover {
color: #fff;
}
#bottombar .divider {
width: 1px;
height: 16px;
background: rgba(255,255,255,0.4);
}
/* ── Responsive ───────────────────────────── */
@media (max-width: 768px) {
#hero h1 { font-size: 36px; }
#hero .tagline { font-size: 18px; }
.section-title { font-size: 24px; }
.flow { flex-direction: column; }
.flow-arrow { transform: rotate(90deg); }
.diff-grid { grid-template-columns: 1fr; }
.card-grid { grid-template-columns: 1fr; }
#main { padding: 40px 16px 120px; }
}
</style>
</head>
<body>
<div id="main">
<!-- ══ Hero ═══════════════════════════════════════ -->
<section id="hero">
<img src="하트로그.gif" alt="하트로그" style="max-width: 480px; width: 80%; margin-bottom: 24px; border-radius: 16px;">
<h1 class="gradient-text">하트로그</h1>
<p class="subtitle">HeartLog — Roguelike Love Matching</p>
<p class="tagline">선택이 쌓여 성향이 되고, 성향이 만나 인연이 된다.</p>
<div id="links">
<a href="https://github.com/inyeon-log-gyeol" class="gradient-bg">
<span class="icon">📦</span> GitHub
</a>
<a href="#demo" class="gradient-bg">
<span class="icon">🎮</span> Demo
</a>
<a href="#architecture" class="gradient-bg">
<span class="icon">📄</span> Docs
</a>
<a href="#team" class="gradient-bg">
<span class="icon">👥</span> Team
</a>
</div>
</section>
<!-- ══ TL;DR ══════════════════════════════════════ -->
<div id="tldr" class="gradient-bg-soft">
<div class="label">TL;DR</div>
<p>
설문은 지루하고, 감은 틀린다. 그래서 우리는 <strong>게임</strong>을 만들었다.<br>
로그라이크 연애 시뮬레이션을 플레이하면, 선택이 자동으로 <strong>15축 성향 벡터</strong>가 되고,<br>
그 벡터가 <strong>실제 매칭</strong>으로 이어진다.
</p>
</div>
<!-- ══ How It Works ═══════════════════════════════ -->
<section id="how-it-works">
<h2 class="section-title gradient-text">How It Works</h2>
<div class="flow">
<div class="flow-step">
<span class="step-emoji">🎮</span> Love Run 플레이
</div>
<span class="flow-arrow"></span>
<div class="flow-step">
<span class="step-emoji">🧠</span> 이벤트 선택 누적
</div>
<span class="flow-arrow"></span>
<div class="flow-step">
<span class="step-emoji">📊</span> 15축 성향 벡터
</div>
<span class="flow-arrow"></span>
<div class="flow-step">
<span class="step-emoji">💜</span> 인연 매칭
</div>
</div>
</section>
<!-- ══ Features ════════════════════════════════════ -->
<section id="features">
<h2 class="section-title gradient-text">왜 로그라이크인가</h2>
<div class="card-grid">
<div class="card">
<div class="card-emoji">🎲</div>
<h3>매번 다른 경험</h3>
<p>같은 시나리오라도 GPT가 유저마다 다른 상황, 다른 선택지를 생성합니다. 반복 플레이할수록 정밀해지는 매칭.</p>
</div>
<div class="card">
<div class="card-emoji">🎭</div>
<h3>정답 없는 선택</h3>
<p>좋고 나쁨이 아닌, 방향이 다를 뿐. 적극적/회피적/관망 — 어떤 선택이든 당신의 진짜 성향을 드러냅니다.</p>
</div>
<div class="card">
<div class="card-emoji">🔬</div>
<h3>과학적 측정</h3>
<p>행동 성향 10축 + Big Five 성격 5축. 총 15개 차원의 벡터로 당신을 정밀하게 분석합니다.</p>
</div>
<div class="card">
<div class="card-emoji">💫</div>
<h3>설문 피로 제로</h3>
<p>지루한 설문 대신 몰입형 게임 플레이. 선택하는 동안 자연스럽게 데이터가 쌓입니다.</p>
</div>
</div>
</section>
<!-- ══ Dating Types ═══════════════════════════════ -->
<section id="types">
<h2 class="section-title gradient-text">연애 유형 카드</h2>
<p class="text-center text-muted" style="margin-bottom: 8px;">플레이 결과에 따라 5가지 유형 중 하나로 분류됩니다.</p>
<div class="type-grid">
<div class="type-card">
<span class="type-emoji">🔥</span>
<div class="type-name">불꽃형</div>
<div class="type-desc">빠른 감정, 직진, 모험</div>
</div>
<div class="type-card">
<span class="type-emoji">🌿</span>
<div class="type-name">안정형</div>
<div class="type-desc">협력, 계획, 신뢰</div>
</div>
<div class="type-card">
<span class="type-emoji">🌊</span>
<div class="type-name">감정형</div>
<div class="type-desc">깊은 감정, 공감, 몰입</div>
</div>
<div class="type-card">
<span class="type-emoji">🧠</span>
<div class="type-name">전략형</div>
<div class="type-desc">리더십, 설계, 주도</div>
</div>
<div class="type-card">
<span class="type-emoji">🫧</span>
<div class="type-name">자유형</div>
<div class="type-desc">독립, 개방, 유연</div>
</div>
</div>
</section>
<!-- ══ Scenario Framework ═════════════════════════ -->
<section id="scenarios">
<h2 class="section-title gradient-text">시나리오 프레임워크</h2>
<p class="text-center text-muted">3단계 뎁스 — 톤 → 상황 카테고리 → GPT 생성 이벤트</p>
<div class="scenario-section">
<h3>💗 긍정 시나리오</h3>
<div class="scenario-grid">
<div class="scenario-item positive">
<div class="scenario-name">첫 인상</div>
<div class="scenario-desc">처음 만난 순간의 반응</div>
<div class="scenario-axes">pace · extraversion</div>
</div>
<div class="scenario-item positive">
<div class="scenario-name">관심 표현</div>
<div class="scenario-desc">호감을 어떻게 드러내는가</div>
<div class="scenario-axes">affection · contact_frequency</div>
</div>
<div class="scenario-item positive">
<div class="scenario-name">깊은 대화</div>
<div class="scenario-desc">감정을 나누는 순간</div>
<div class="scenario-axes">emotional_depth · openness</div>
</div>
<div class="scenario-item positive">
<div class="scenario-name">함께하는 시간</div>
<div class="scenario-desc">데이트 중 선택</div>
<div class="scenario-axes">humor · cooperation</div>
</div>
<div class="scenario-item positive">
<div class="scenario-name">미래 이야기</div>
<div class="scenario-desc">관계의 다음 단계</div>
<div class="scenario-axes">planning · conscientiousness</div>
</div>
<div class="scenario-item positive">
<div class="scenario-name">서프라이즈</div>
<div class="scenario-desc">상대를 위한 행동</div>
<div class="scenario-axes">affection · agreeableness</div>
</div>
</div>
</div>
<div class="scenario-section">
<h3>💔 부정 시나리오</h3>
<div class="scenario-grid">
<div class="scenario-item negative">
<div class="scenario-name">연락 두절</div>
<div class="scenario-desc">갑자기 답이 없다</div>
<div class="scenario-axes">jealousy · neuroticism</div>
</div>
<div class="scenario-item negative">
<div class="scenario-name">의견 충돌</div>
<div class="scenario-desc">서로 다른 생각</div>
<div class="scenario-axes">cooperation · agreeableness</div>
</div>
<div class="scenario-item negative">
<div class="scenario-name">질투 상황</div>
<div class="scenario-desc">다른 이성의 등장</div>
<div class="scenario-axes">jealousy · neuroticism</div>
</div>
<div class="scenario-item negative">
<div class="scenario-name">실망 순간</div>
<div class="scenario-desc">기대와 다른 모습 발견</div>
<div class="scenario-axes">emotional_depth · conscientiousness</div>
</div>
<div class="scenario-item negative">
<div class="scenario-name">거리감</div>
<div class="scenario-desc">상대가 한 발 물러섬</div>
<div class="scenario-axes">pace · contact_frequency</div>
</div>
<div class="scenario-item negative">
<div class="scenario-name">과거 등장</div>
<div class="scenario-desc">전 애인 관련 상황</div>
<div class="scenario-axes">risk · neuroticism</div>
</div>
</div>
</div>
<div class="scenario-section">
<h3>⚡ 돌발 시나리오</h3>
<div class="scenario-grid">
<div class="scenario-item wildcard">
<div class="scenario-name">우연한 재회</div>
<div class="scenario-desc">예상 못한 곳에서 마주침</div>
<div class="scenario-axes">extraversion · pace</div>
</div>
<div class="scenario-item wildcard">
<div class="scenario-name">제3자 개입</div>
<div class="scenario-desc">친구/가족의 의견</div>
<div class="scenario-axes">leadership · agreeableness</div>
</div>
<div class="scenario-item wildcard">
<div class="scenario-name">돌발 고백</div>
<div class="scenario-desc">예상보다 빠른 감정 표현</div>
<div class="scenario-axes">risk · pace</div>
</div>
<div class="scenario-item wildcard">
<div class="scenario-name">환경 변화</div>
<div class="scenario-desc">이사/이직 등 외부 변수</div>
<div class="scenario-axes">planning · openness</div>
</div>
<div class="scenario-item wildcard">
<div class="scenario-name">오해 발생</div>
<div class="scenario-desc">의도와 다르게 전달된 상황</div>
<div class="scenario-axes">cooperation · emotional_depth</div>
</div>
<div class="scenario-item wildcard">
<div class="scenario-name">시험대</div>
<div class="scenario-desc">관계를 증명해야 하는 순간</div>
<div class="scenario-axes">risk · leadership</div>
</div>
</div>
</div>
</section>
<!-- ══ Event Structure ════════════════════════════ -->
<section id="event-structure">
<h2 class="section-title gradient-text">이벤트 2턴 구조</h2>
<p class="text-center text-muted" style="margin-bottom: 8px;">1턴 = 행동의 방향 · 2턴 = 표현의 방식</p>
<div class="event-flow">
<div class="event-step gradient-bg-soft">
<strong>감정 태그</strong> — 상황 제시 전, 유저의 첫 감정 선택
</div>
<div class="event-arrow"></div>
<div class="event-step">
<strong>상황 묘사</strong> — 감각적 서사로 장면을 보여준다
</div>
<div class="event-arrow"></div>
<div class="event-step" style="border-left: 4px solid #7c3aed;">
<strong>[1턴]</strong> 행동 방향 선택 — 다가간다 / 피한다 / 지켜본다
</div>
<div class="event-arrow"></div>
<div class="event-step">
<strong>상황 전개</strong> — 1턴 선택에 따라 완전히 다른 전개
</div>
<div class="event-arrow"></div>
<div class="event-step" style="border-left: 4px solid #ec4899;">
<strong>[2턴]</strong> 표현 방식 선택 — 진지하게 / 장난스럽게 / 차갑게
</div>
<div class="event-arrow"></div>
<div class="event-step gradient-bg-soft">
<strong>Trait 벡터 업데이트</strong> — 감정태그 + 1턴 + 2턴 종합 반영
</div>
</div>
</section>
<!-- ══ Architecture ═══════════════════════════════ -->
<section id="architecture">
<h2 class="section-title gradient-text">시스템 아키텍처</h2>
<table class="arch-table">
<tr>
<td>🎮 Love Run</td>
<td>로그라이크 연애 시뮬레이션 — 6이벤트 + 보스(5%) 랜덤 구성</td>
</tr>
<tr>
<td>🧠 GPT Engine</td>
<td>시나리오 프레임 기반 동적 이벤트 생성 — 연결된 서사, 분기형 선택지</td>
</tr>
<tr>
<td>📊 Trait Engine</td>
<td>선택 → 행동 10축 + Big Five 5축 벡터 변환 · 런 안정화(0.6:0.4)</td>
</tr>
<tr>
<td>🏷️ Cluster</td>
<td>15축 벡터 → 5가지 연애 유형 카드 분류</td>
</tr>
<tr>
<td>💞 Matching</td>
<td>행동 유사도(0.4) + Big5 유사도(0.3) + 군집(0.2) + 다양성(0.1)</td>
</tr>
</table>
</section>
<!-- ══ Comparison ═════════════════════════════════ -->
<section id="comparison">
<h2 class="section-title gradient-text">차별점</h2>
<div class="diff-grid">
<div class="diff-card old">
<h4>기존 매칭 앱</h4>
<p>사진 + 프로필 스펙<br>기반 스와이프</p>
</div>
<div class="diff-card old">
<h4>심리 테스트 앱</h4>
<p>설문 → 유형 분류<br>→ 끝</p>
</div>
<div class="diff-card ours">
<h4>💜 하트로그</h4>
<p>플레이 → 성향 벡터<br>→ 심리 모델 보정<br>→ 수학적 매칭</p>
</div>
</div>
</section>
<!-- ══ Demo ═══════════════════════════════════════ -->
<section id="demo">
<h2 class="section-title gradient-text">Demo</h2>
<div class="text-center" style="padding: 48px 0;">
<p class="text-muted" style="font-size: 16px; margin-bottom: 24px;">Gradio 기반 프로토타입으로 직접 플레이해보세요.</p>
<a href="#" class="gradient-bg" style="display: inline-flex; align-items: center; gap: 8px; padding: 14px 32px; color: #fff; font-size: 18px; font-weight: 700; border-radius: 50px; box-shadow: 0 0 6px rgba(0,0,0,0.3); transition: all 0.2s ease;">
🎮 Love Run 시작하기
</a>
</div>
</section>
<!-- ══ Team ═══════════════════════════════════════ -->
<section id="team">
<h2 class="section-title gradient-text">Team</h2>
<div class="team-grid">
<div class="team-card">
<span class="role gradient-bg">AI Engineer A</span>
<div class="name">시나리오 생성</div>
<div class="desc">이벤트 스키마 · GPT 프롬프트<br>축 커버리지 · 안전 필터</div>
</div>
<div class="team-card">
<span class="role gradient-bg">AI Engineer B</span>
<div class="name">Traits / 매칭</div>
<div class="desc">15축 계산 · 유형 분류<br>코사인 매칭 · 보정 점수</div>
</div>
<div class="team-card">
<span class="role gradient-bg">AI Engineer C</span>
<div class="name">대화 / 게임 / 안전</div>
<div class="desc">가이드 대화 · 미니게임<br>DM 필터링 · 이상 탐지</div>
</div>
</div>
</section>
</div>
<!-- ══ Bottom Bar ══════════════════════════════════ -->
<div id="bottombar" class="gradient-bg">
<span>💜 하트로그 HeartLog</span>
<div class="divider"></div>
<a href="https://github.com/inyeon-log-gyeol">GitHub</a>
<div class="divider"></div>
<span>선택이 쌓여 성향이 되고, 성향이 만나 인연이 된다.</span>
</div>
</body>
</html>