Public Source Viewer

비나래아카이브 개발자 포털

실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.

Redacted View
view/hinana/lounge.ejs
공개 가능
1 <!DOCTYPE html>
2 <html lang="ko" xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="color-scheme" content="light dark">
6 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, maximum-scale=1.0">
7 <link rel="manifest" href="/manifest.json">
8 <meta name="theme-color" content="<%= (typeof theme !== 'undefined' && theme === 'dark') ? '#0f141e' : '#f8f7f5' %>">
9 <meta name="apple-mobile-web-app-title" content="비나래 라운지">
10 <meta property="og:image" content="/image/train_hinana.png" />
11 <meta property="og:description" content="비나래 라운지"/>
12 <meta property="og:url" content="hinana.moe/hinana/lounge"/>
13 <meta property="og:title" content="비나래 라운지"/>
14 <title>비나래 라운지</title>
15
16 <link rel='stylesheet' href='/vendors/bootstrap/css/bootstrap.min.css' />
17 <script src="/vendors/bootstrap/js/bootstrap.min.js"></script>
18 <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
19 <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet" type="text/css">
20 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
21
22 <style>
23 :root {
24 --font-family: 'Noto Sans KR', sans-serif;
25 --bg-main: #f8f7f5; --bg-secondary: #ffffff; --bg-tertiary: #1a2238;
26 --text-primary: #1a2238; --text-secondary: #5e6676;
27 --accent-color: #c5a059; --danger-color: #dc2626; --border-color: #e5e1da;
28 --shadow-md: 0 10px 40px -10px rgba(26, 34, 56, 0.12);
29 --shadow-sm: 0 2px 8px rgba(0,0,0,0.05);
30 }
31
32 body.dark-mode {
33 --bg-main: #0f141e; --bg-secondary: #1a2238; --bg-tertiary: #0a0e17;
34 --text-primary: #e7e5e4; --text-secondary: #a8a29e;
35 --accent-color: #d4b47a; --border-color: #2e3a59;
36 }
37
38 html, body {
39 height: auto !important; min-height: 100%; margin: 0; padding: 0;
40 font-family: var(--font-family); background-color: var(--bg-main); color: var(--text-primary);
41 overflow-x: hidden; overflow-y: auto; width: 100%;
42 }
43
44 a { text-decoration: none; color: inherit; }
45
46 /* [Header] */
47 .global-header {
48 height: 60px; background-color: var(--bg-tertiary); border-bottom: 1px solid var(--border-color);
49 display: flex; align-items: center; justify-content: space-between; padding: 0 40px;
50 position: sticky; top: 0; z-index: 1000; color: white; flex-wrap: wrap;
51 }
52 .header-logo { height: 32px; }
53 body:not(.dark-mode) .logo-night { display: none; }
54 body.dark-mode .logo-day { display: none; }
55 .header-brand { display: flex; align-items: center; flex: 0 0 auto; }
56 .header-nav { display: flex; gap: 20px; align-items: center; transition: all 0.3s ease; }
57
58 /* [Layout] */
59 .layout-container {
60 display: flex;
61 min-height: calc(100vh - 60px);
62 background-color: var(--bg-main);
63 width: 100%; max-width: 100vw; overflow-x: hidden;
64 }
65
66 /* [Content Column] */
67 .content-column {
68 flex: 1; padding: 60px 40px;
69 display: flex; flex-direction: column; align-items: center;
70 width: 100%; min-width: 0;
71 }
72
73 .lounge-hero { text-align: center; margin-bottom: 50px; }
74 .info-title { font-size: 2.8rem; font-weight: 700; color: var(--text-primary); margin: 15px 0; letter-spacing: -1px; }
75
76 .effect-box { position: relative; height: 300px; width: 100%; max-width: 500px; display: flex; justify-content: center; align-items: center; margin-bottom: 30px; }
77 .effect-box img {
78 position: absolute; width: 100%; height: 240px;
79 object-fit: cover; border: 1px solid var(--accent-color); border-radius: 2px;
80 box-shadow: var(--shadow-md);
81 }
82
83 .luxury-card {
84 width: 100%; max-width: 800px; background-color: var(--bg-secondary);
85 padding: 40px; border-radius: 4px; border: 1px solid var(--border-color);
86 border-top: 5px solid var(--accent-color) !important; box-shadow: var(--shadow-md);
87 }
88
89 .service-btn {
90 display: block; text-align: center; padding: 25px;
91 border: 1px solid var(--border-color); border-radius: 4px;
92 background-color: var(--bg-main); transition: all 0.2s;
93 color: var(--text-primary);
94 text-decoration: none;
95 }
96 .service-btn:hover {
97 transform: translateY(-5px);
98 border-color: var(--accent-color);
99 box-shadow: var(--shadow-md);
100 color: var(--accent-color);
101 }
102
103 /* [Right Sidebar] */
104 .info-column {
105 flex: 0 0 320px;
106 width: 320px;
107 background-color: var(--bg-secondary);
108 border-left: 1px solid var(--border-color);
109 padding: 40px 0;
110 display: flex; flex-direction: column; align-items: center;
111 }
112
113 .info-card {
114 width: 270px;
115 background-color: var(--bg-main);
116 border: 1px solid var(--border-color);
117 border-radius: 12px;
118 padding: 24px 20px;
119 margin-bottom: 20px;
120 box-shadow: var(--shadow-sm);
121 }
122
123 /* [Responsive] */
124 @media (max-width: 1200px) {
125 .global-header { padding: 10px 20px; }
126 .layout-container { flex-direction: column; align-items: center; }
127 .content-column { width: 100%; padding: 40px 20px; }
128
129 .info-column {
130 width: 100%; flex: auto;
131 border-left: none; border-top: 1px solid var(--border-color);
132 padding: 40px 20px;
133 }
134 .info-card { width: 100%; }
135 .info-column > div:last-child { margin-bottom: 60px; }
136 }
137
138 @media (max-width: 991px) {
139 .global-header { height: auto; min-height: 60px; padding: 10px 15px; }
140 .header-brand { order: 1; }
141 .header-nav { gap: 15px !important; order: 2; margin-left: auto; }
142 .header-controls {
143 width: 100%; order: 3; display: flex; justify-content: flex-end;
144 margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.15);
145 }
146 }
147 .verified-badge { color: #1d9bf0; font-size: 0.85em; margin-left: 2px; }
148 .verified-badge-admin { color: var(--accent-color); font-size: 0.85em; margin-left: 2px; }
149
150 .service-btn span {
151 display: -webkit-box;
152 -webkit-line-clamp: 2;
153 line-clamp: 2;
154 -webkit-box-orient: vertical;
155 overflow: hidden;
156 min-height: 2.8em;
157 display: flex;
158 align-items: center;
159 justify-content: center;
160 line-height: 1.2;
161 }
162 </style>
163 </head>
164
165 <body class="<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'dark-mode' : '' %>">
166 <header class="global-header">
167 <div class="header-brand">
168 <a href="/hinana/lounge">
169 <img src="/image/lounge1.png" alt="비나래 라운지" class="header-logo">
170 </a>
171 </div>
172 <nav class="header-nav">
173 <a href="/hinana/index" class="nav-link text-white-50 small fw-bold">Archive</a>
174 <a href="/hinana/lounge" class="nav-link text-white fw-bold">Lounge</a>
175 <a href="/hinana/gallery" class="nav-link text-white-50 small fw-bold">Gallery</a>
176 </nav>
177 <div class="header-controls" style="display:flex; align-items:center; gap:12px;">
178 <a href="/hinana/gallery#brand-assets" class="text-white-50 small fw-bold" style="text-decoration:none;">사이트 맵</a>
179 <form action="/toggle-theme" method="POST" style="margin:0;">
180 <button type="submit" class="btn text-white p-1"><i class="bi bi-moon-stars"></i></button>
181 </form>
182 </div>
183 </header>
184
185 <div class="layout-container">
186 <div class="content-column">
187 <div class="lounge-hero">
188 <span style="color: var(--accent-color); letter-spacing: 5px; font-weight: bold; font-size: 0.8rem;">ESTABLISHED 2026</span>
189 <h2 class="info-title">비나래 라운지</h2>
190 <div style="width: 60px; height: 1px; background: var(--accent-color); margin: 0 auto;"></div>
191 </div>
192
193 <div class="effect-box">
194 <img src="/image/<%= randomLoungeImage %>" style="transform: rotate(-6deg) scale(0.9); opacity: 0.3;">
195 <img src="/image/<%= randomLoungeImage %>" style="transform: rotate(-3deg) scale(0.95); opacity: 0.6;">
196 <img src="/image/<%= randomLoungeImage %>" style="z-index: 3;">
197 </div>
198
199 <div class="text-center mb-5" style="max-width: 600px;">
200 <h4 class="fw-light mb-3" style="color: var(--accent-color)">고요한 아카이브와 라운지의 만남</h4>
201 <p class="text-secondary">아카이브를 나와 라운지로. 히나나와 함께.</p>
202 </div>
203
204 <div class="luxury-card">
205 <div class="row g-4 justify-content-center">
206
207 <div class="col-6 col-md-3">
208 <a href="/hinana/gallery" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
209 <i class="bi bi-palette fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
210 <span class="fw-bold small">라운지 갤러리</span>
211 </a>
212 </div>
213
214 <div class="col-6 col-md-3">
215 <a href="/hinana/plaza" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
216 <i class="bi bi-chat-dots fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
217 <span class="fw-bold small">비나래 광장</span>
218 </a>
219 </div>
220
221 <div class="col-6 col-md-3">
222 <a href="/hinana/tetris" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
223 <i class="bi bi-controller fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
224 <span class="fw-bold small">TETRIS</span>
225 </a>
226 </div>
227
228 <div class="col-6 col-md-3">
229 <a href="/hinana/train" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
230 <i class="bi bi-train-front fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
231 <span class="fw-bold small">특급 히나나호</span>
232 </a>
233 </div>
234
235 <div class="col-6 col-md-3">
236 <a href="/hinana/shop" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
237 <i class="bi bi-bookmark-star fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
238 <span class="fw-bold small">책갈피 교환소</span>
239 </a>
240 </div>
241
242 <div class="col-6 col-md-3">
243 <a href="/hinana/image" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
244 <i class="bi bi-image fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
245 <span class="fw-bold small">이미지 편집기</span>
246 </a>
247 </div>
248 <div class="col-6 col-md-3">
249 <a href="/hinana/exhibition" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
250 <i class="bi bi-easel2 fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
251 <span class="fw-bold small">특별전</span>
252 <span style="font-size:0.65rem; color:var(--text-secondary); margin-top:2px;">Claude Design 테스트</span>
253 </a>
254 </div>
255 <div class="col-6 col-md-3">
256 <a href="/hinana/echo" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
257 <i class="bi bi-soundwave fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
258 <span class="fw-bold small">에코 스튜디오</span>
259 </a>
260 </div>
261 <div class="col-6 col-md-3">
262 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
263 <i class="bi bi-calculator fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
264 <span class="fw-bold small">AI 토큰 계산기</span>
265 </a>
266 </div>
267 <div class="col-6 col-md-3">
268 <a href="/hinana/subway" class="service-btn h-100 d-flex flex-column justify-content-center align-items-center">
269 <i class="bi bi-train-front fs-2 mb-2 d-block" style="color: var(--accent-color)"></i>
270 <span class="fw-bold small">열차 위치 조회</span>
271 </a>
272 </div>
273 </div>
274 </div>
275 </div>
276
277 <div class="info-column">
278 <div class="info-card text-center">
279 <div style="font-size: 0.65rem; color: var(--accent-color); letter-spacing: 3px; font-weight: 700; margin-bottom: 20px;">PASSENGER INFO</div>
280 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
281
282 <div>
283 <% if(username) { %>
284 <a href="/logout?redirect=/hinana/lounge" class="btn btn-outline-dark btn-sm w-100 py-2" style="letter-spacing: 1px;">SIGN OUT</a>
285 <% } else { %>
286 <a href="/login?redirect=/hinana/lounge" class="btn btn-dark btn-sm w-100 py-2" style="letter-spacing: 1px;">SIGN IN</a>
287 <% } %>
288 </div>
289 </div>
290
291 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
292 <div class="info-card border-warning shadow-sm">
293 <div class="small fw-bold text-warning mb-3"><i class="bi bi-gear-wide-connected me-2"></i> ADMINISTRATION</div>
294 <a href="/hinana/admin" class="d-flex justify-content-between align-items-center text-decoration-none" style="color: inherit;">
295 <span class="small"><i class="bi bi-bookmark-star-fill me-1"></i> 책갈피 관리</span>
296 <i class="bi bi-chevron-right text-secondary"></i>
297 </a>
298 </div>
299 <% } %>
300
301 <div class="info-card">
302 <div style="font-size: 0.65rem; color: var(--accent-color); letter-spacing: 3px; font-weight: 700; margin-bottom: 15px;">SYSTEM INFO</div>
303 <ul class="small text-secondary list-unstyled mb-0" style="font-size: 0.75rem;">
304 <li class="mb-1 d-flex justify-content-between">
305 <span>Version</span>
306 <span class="text-end">Ver. 6.5.4.0-Kozeki Ui</span>
307 </li>
308 </ul>
309 </div>
310
311 <div class="mt-auto text-center pt-5">
312 <img src="/image/sign.png" style="width: 160px; opacity: 0.7; mix-blend-mode: multiply;">
313 <div class="mt-4 pt-4 border-top" style="font-size: 0.7rem; color: var(--text-secondary); line-height: 1.8;">
314 <strong>비나래 라운지</strong><br>
315 X - @NoctchillHinana<br>
316 ⓒ 2024~2026. 비나래 | hinana.moe
317 </div>
318 </div>
319 </div>
320 </div>
321
322 <script src="/js/popup.js"></script>
323 <script>if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/sw.js"); }</script>
324 </body>
325 </html>
326