Public Source Viewer

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

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

Redacted View
view/hinana/gallery.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/lounge1.png" />
11 <meta property="og:description" content="비나래 라운지 갤러리"/>
12 <meta property="og:url" content="hinana.moe/hinana/gallery"/>
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; --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 a { text-decoration: none; color: inherit; }
44
45 .global-header {
46 height: 60px; background-color: var(--bg-tertiary); border-bottom: 1px solid var(--border-color);
47 display: flex; align-items: center; justify-content: space-between; padding: 0 40px;
48 position: sticky; top: 0; z-index: 1000; color: white; flex-wrap: wrap;
49 }
50 .header-logo { height: 32px; filter: none !important; -webkit-filter: none !important; mix-blend-mode: normal !important; }
51 .header-brand { display: flex; align-items: center; flex: 0 0 auto; }
52 .header-nav { display: flex; gap: 20px; align-items: center; transition: all 0.3s ease; }
53
54 /* [Layout] */
55 .layout-container {
56 display: flex;
57 min-height: calc(100vh - 60px);
58 background-color: var(--bg-main);
59 width: 100%; max-width: 100vw; overflow-x: hidden;
60 }
61
62 .content-column {
63 flex: 1; padding: 60px 40px;
64 display: flex; flex-direction: column; align-items: center;
65 width: 100%; min-width: 0;
66 }
67
68 /* [Right Sidebar] */
69 .info-column {
70 flex: 0 0 320px;
71 width: 320px;
72 background-color: var(--bg-secondary);
73 border-left: 1px solid var(--border-color);
74 padding: 40px 0;
75 display: flex; flex-direction: column; align-items: center;
76 }
77
78 .info-card {
79 width: 270px;
80 background-color: var(--bg-main);
81 border: 1px solid var(--border-color);
82 border-radius: 12px;
83 padding: 24px 20px;
84 margin-bottom: 20px;
85 box-shadow: var(--shadow-sm);
86 }
87
88 .gallery-hero { text-align: center; margin-bottom: 50px; }
89 .gallery-title { font-size: 2.8rem; font-weight: 700; color: var(--text-primary); margin: 15px 0; letter-spacing: -1px; }
90
91 .gallery-section {
92 width: 100%; background-color: var(--bg-secondary);
93 padding: 40px; border-radius: 4px; border: 1px solid var(--border-color);
94 border-top: 5px solid var(--accent-color) !important; box-shadow: var(--shadow-md);
95 margin-bottom: 40px;
96 }
97
98 .section-label {
99 font-size: 0.65rem; color: var(--accent-color); letter-spacing: 3px;
100 font-weight: 700; text-transform: uppercase; margin-bottom: 10px;
101 }
102 .section-title {
103 font-size: 1.3rem; font-weight: 700; margin-bottom: 30px;
104 padding-bottom: 15px; border-bottom: 1px solid var(--border-color);
105 }
106
107 .color-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 20px; }
108 .color-card {
109 border: 1px solid var(--border-color); border-radius: 8px; overflow: hidden;
110 background-color: var(--bg-main); transition: all 0.2s;
111 }
112 .color-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
113 .color-swatch { height: 80px; width: 100%; }
114 .color-info { padding: 12px 14px; }
115 .color-name { font-weight: 700; font-size: 0.85rem; margin-bottom: 2px; }
116 .color-hex { font-size: 0.75rem; color: var(--text-secondary); font-family: 'Courier New', monospace; }
117
118 .logo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px; }
119 .logo-card {
120 border: 1px solid var(--border-color); border-radius: 8px; overflow: hidden;
121 background-color: var(--bg-main); text-align: center; padding: 30px 20px;
122 transition: all 0.2s; cursor: pointer;
123 }
124 .logo-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--accent-color); }
125 .logo-card img { max-height: 48px; max-width: 100%; object-fit: contain; margin-bottom: 15px; }
126 .logo-label { font-weight: 700; font-size: 0.85rem; }
127
128 .gallery-modal .modal-content {
129 background-color: var(--bg-secondary); color: var(--text-primary);
130 border: 1px solid var(--border-color); border-radius: 8px;
131 border-top: 4px solid var(--accent-color);
132 }
133 .gallery-modal .modal-header { border-bottom: 1px solid var(--border-color); }
134 body.dark-mode .gallery-modal .btn-close { filter: invert(1); }
135 .gallery-modal .modal-body { padding: 25px 30px; }
136 .gallery-modal .service-item {
137 display: flex; align-items: center; gap: 15px;
138 padding: 16px; margin-bottom: 12px;
139 background-color: var(--bg-main); border: 1px solid var(--border-color);
140 border-radius: 8px; transition: all 0.2s; text-decoration: none; color: inherit;
141 }
142 .gallery-modal .service-item:hover {
143 border-color: var(--accent-color); transform: translateX(5px); box-shadow: var(--shadow-sm);
144 }
145 .gallery-modal .service-item:last-child { margin-bottom: 0; }
146 .gallery-modal .service-icon {
147 width: 40px; height: 40px; border-radius: 8px;
148 background-color: var(--bg-secondary); display: flex; align-items: center; justify-content: center;
149 font-size: 1.2rem; color: var(--accent-color); flex-shrink: 0;
150 }
151 .gallery-modal .service-name { font-weight: 700; font-size: 0.9rem; margin-bottom: 2px; }
152 .gallery-modal .service-desc { font-size: 0.75rem; color: var(--text-secondary); }
153
154 @media (max-width: 1200px) {
155 .global-header { padding: 10px 20px; }
156 .layout-container { flex-direction: column; align-items: center; }
157 .content-column { width: 100%; padding: 40px 20px; }
158
159 .info-column {
160 width: 100%; flex: auto;
161 border-left: none; border-top: 1px solid var(--border-color);
162 padding: 40px 20px;
163 }
164 .info-card { width: 100%; }
165 .info-column > div:last-child { margin-bottom: 60px; }
166 }
167
168 @media (max-width: 991px) {
169 .global-header { height: auto; min-height: 60px; padding: 10px 15px; }
170 .header-brand { order: 1; }
171 .header-nav { gap: 15px !important; order: 2; margin-left: auto; }
172 .header-controls {
173 width: 100%; order: 3; display: flex; justify-content: flex-end;
174 margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.15);
175 }
176 }
177
178 @media (max-width: 768px) {
179 .content-column { padding: 30px 15px; }
180 .gallery-section { padding: 25px 18px; }
181 .gallery-title { font-size: 2rem; }
182 .color-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
183 .logo-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
184 }
185 </style>
186 <link rel="stylesheet" href="/css/lounge-modern.css">
187 </head>
188
189 <body class="lounge-fixed-nav <%= (typeof theme !== 'undefined' && theme === 'dark') ? 'dark-mode' : '' %>">
190 <header class="global-header">
191 <div class="header-brand">
192 <a href="/hinana/lounge">
193 <img src="/image/<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'lounge1.png' : 'lounge.png' %>" alt="Logo" class="header-logo">
194 </a>
195 </div>
196 <nav class="header-nav">
197 <a href="/hinana/index" class="nav-link text-white-50 small fw-bold">Archive</a>
198 <a href="/hinana/lounge" class="nav-link text-white-50 small fw-bold">Lounge</a>
199 <a href="/hinana/gallery" class="nav-link text-white fw-bold">Gallery</a>
200 </nav>
201 <div class="header-controls" style="display:flex; align-items:center; gap:12px;">
202 <a href="#brand-assets" class="text-white-50 small fw-bold" style="text-decoration:none;">사이트 맵</a>
203 <form action="/toggle-theme" method="POST" style="margin:0;">
204 <button type="submit" class="btn text-white p-1"><i class="bi bi-moon-stars"></i></button>
205 </form>
206 </div>
207 </header>
208
209 <div class="layout-container">
210 <div class="content-column">
211
212 <div class="gallery-hero">
213 <span style="color: var(--accent-color); letter-spacing: 5px; font-weight: bold; font-size: 0.8rem;">LOUNGE GALLERY</span>
214 <h2 class="gallery-title">라운지 갤러리</h2>
215 <div style="width: 60px; height: 1px; background: var(--accent-color); margin: 0 auto;"></div>
216 <p class="text-secondary mt-3">비나래아카이브와 비나래 라운지의 디자인 및 서비스들을 소개합니다.</p>
217 </div>
218
219 <!-- 색상 팔레트 섹션 -->
220 <div class="gallery-section">
221 <div class="section-label">COLOR PALETTE</div>
222 <div class="section-title">비나래아카이브와 비나래 라운지에는 이런 색들이 사용되었어요.</div>
223
224 <div class="color-grid">
225 <div class="color-card">
226 <div class="color-swatch" style="background-color: #FFC639;"></div>
227 <div class="color-info">
228 <div class="color-name">히나나 옐로우</div>
229 <div class="color-hex">#FFC639</div>
230 </div>
231 </div>
232 <div class="color-card">
233 <div class="color-swatch" style="background-color: #1a2238;"></div>
234 <div class="color-info">
235 <div class="color-name">비나래 다크 블루</div>
236 <div class="color-hex">#1a2238</div>
237 </div>
238 </div>
239 <div class="color-card">
240 <div class="color-swatch" style="background-color: #b45309;"></div>
241 <div class="color-info">
242 <div class="color-name">비나래 아카이브 브라운</div>
243 <div class="color-hex">#b45309</div>
244 </div>
245 </div>
246 <div class="color-card">
247 <div class="color-swatch" style="background-color: #c5a059;"></div>
248 <div class="color-info">
249 <div class="color-name">비나래 라운지 골드</div>
250 <div class="color-hex">#c5a059</div>
251 </div>
252 </div>
253 <div class="color-card">
254 <div class="color-swatch" style="background-color: #e4dfd7;"></div>
255 <div class="color-info">
256 <div class="color-name">비나래 아카이브 베이지</div>
257 <div class="color-hex">#e4dfd7</div>
258 </div>
259 </div>
260 <div class="color-card">
261 <div class="color-swatch" style="background-color: #f8f7f5;"></div>
262 <div class="color-info">
263 <div class="color-name">비나래 라운지 아이보리</div>
264 <div class="color-hex">#f8f7f5</div>
265 </div>
266 </div>
267 <div class="color-card">
268 <div class="color-swatch" style="background-color: #0f141e;"></div>
269 <div class="color-info">
270 <div class="color-name">비나래 다크모드 블랙</div>
271 <div class="color-hex">#0f141e</div>
272 </div>
273 </div>
274 <div class="color-card">
275 <div class="color-swatch" style="background-color: #1c1917;"></div>
276 <div class="color-info">
277 <div class="color-name">비나래 아카이브 다크</div>
278 <div class="color-hex">#1c1917</div>
279 </div>
280 </div>
281 <div class="color-card">
282 <div class="color-swatch" style="background-color: #f2f0eb;"></div>
283 <div class="color-info">
284 <div class="color-name">비나래 아카이브 크림</div>
285 <div class="color-hex">#f2f0eb</div>
286 </div>
287 </div>
288 <div class="color-card">
289 <div class="color-swatch" style="background-color: #3e3a36;"></div>
290 <div class="color-info">
291 <div class="color-name">비나래 아카이브 차콜</div>
292 <div class="color-hex">#3e3a36</div>
293 </div>
294 </div>
295 <div class="color-card">
296 <div class="color-swatch" style="background-color: #f59e0b;"></div>
297 <div class="color-info">
298 <div class="color-name">비나래 아카이브 다크모드 앰버</div>
299 <div class="color-hex">#f59e0b</div>
300 </div>
301 </div>
302 <div class="color-card">
303 <div class="color-swatch" style="background-color: #d4b47a;"></div>
304 <div class="color-info">
305 <div class="color-name">비나래 라운지 다크모드 골드</div>
306 <div class="color-hex">#d4b47a</div>
307 </div>
308 </div>
309 <div class="color-card">
310 <div class="color-swatch" style="background-color: #0a0e17;"></div>
311 <div class="color-info">
312 <div class="color-name">특급 히나나호 나이트</div>
313 <div class="color-hex">#0a0e17</div>
314 </div>
315 </div>
316 <div class="color-card">
317 <div class="color-swatch" style="background-color: #1d9bf0;"></div>
318 <div class="color-info">
319 <div class="color-name">비나래 체크마크 블루</div>
320 <div class="color-hex">#1d9bf0</div>
321 </div>
322 </div>
323 <div class="color-card">
324 <div class="color-swatch" style="background-color: #dc2626;"></div>
325 <div class="color-info">
326 <div class="color-name">비나래 레드</div>
327 <div class="color-hex">#dc2626</div>
328 </div>
329 </div>
330 </div>
331 </div>
332
333 <!-- 로고/서비스 섹션 -->
334 <div class="gallery-section" id="brand-assets">
335 <div class="section-label">BRAND ASSETS</div>
336 <div class="section-title">현재 이런 서비스들을 제공하고 있죠.<span style="font-size:0.7em;">(터치 및 클릭시 팝업)</span></div>
337
338 <div class="logo-grid">
339 <div class="logo-card" data-bs-toggle="modal" data-bs-target="#archiveModal">
340 <img src="/image/<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'archive1.png' : 'archive.png' %>" alt="비나래아카이브">
341 <div class="logo-label">비나래아카이브</div>
342 </div>
343 <div class="logo-card" data-bs-toggle="modal" data-bs-target="#libraryModal">
344 <img src="/image/<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'library1.png' : 'library.png' %>" alt="비나래아카이브 도서관">
345 <div class="logo-label">비나래아카이브 도서관</div>
346 </div>
347 <div class="logo-card" data-bs-toggle="modal" data-bs-target="#loungeModal">
348 <img src="/image/<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'lounge1.png' : 'lounge.png' %>" alt="비나래 라운지">
349 <div class="logo-label">비나래 라운지</div>
350 </div>
351 <div class="logo-card" data-bs-toggle="modal" data-bs-target="#railwayModal">
352 <img src="/image/<%= (typeof theme !== 'undefined' && theme === 'dark') ? 'train1.png' : 'train.png' %>" alt="비나래아카이브 철도국">
353 <div class="logo-label">비나래아카이브 철도국</div>
354 </div>
355 </div>
356 </div>
357
358 </div>
359
360 <div class="info-column">
361 <div class="info-card text-center">
362 <div style="font-size: 0.65rem; color: var(--accent-color); letter-spacing: 3px; font-weight: 700; margin-bottom: 20px;">PASSENGER INFO</div>
363 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
364 <div>
365 <% if(username) { %>
366 <a href="/logout?redirect=/hinana/gallery" class="btn btn-outline-dark btn-sm w-100 py-2" style="letter-spacing: 1px;">SIGN OUT</a>
367 <% } else { %>
368 <a href="/login?redirect=/hinana/gallery" class="btn btn-dark btn-sm w-100 py-2" style="letter-spacing: 1px;">SIGN IN</a>
369 <% } %>
370 </div>
371 </div>
372
373 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
374 <div class="info-card border-warning shadow-sm">
375 <div class="small fw-bold text-warning mb-3"><i class="bi bi-gear-wide-connected me-2"></i> ADMINISTRATION</div>
376 <a href="/hinana/admin" class="d-flex justify-content-between align-items-center text-decoration-none" style="color: inherit;">
377 <span class="small"><i class="bi bi-bookmark-star-fill me-1"></i> 책갈피 관리</span>
378 <i class="bi bi-chevron-right text-secondary"></i>
379 </a>
380 </div>
381 <% } %>
382
383 <div class="info-card">
384 <div style="font-size: 0.65rem; color: var(--accent-color); letter-spacing: 3px; font-weight: 700; margin-bottom: 15px;">SYSTEM INFO</div>
385 <ul class="small text-secondary list-unstyled mb-0" style="font-size: 0.75rem;">
386 <li class="mb-1 d-flex justify-content-between">
387 <span>Version</span>
388 <span class="text-end">Ver. 8.0.3.2-Utsumi Aoba</span>
389 </li>
390 </ul>
391 </div>
392
393 </div>
394 </div>
395
396 <!-- 비나래아카이브 모달 -->
397 <div class="modal fade gallery-modal" id="archiveModal" tabindex="-1">
398 <div class="modal-dialog modal-dialog-centered">
399 <div class="modal-content">
400 <div class="modal-header">
401 <h6 class="modal-title fw-bold">비나래아카이브</h6>
402 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
403 </div>
404 <div class="modal-body">
405 <a href="/" class="service-item">
406 <div class="service-icon"><i class="bi bi-house-door"></i></div>
407 <div>
408 <div class="service-name">메인 화면</div>
409 <div class="service-desc">hinana.moe의 첫 번째 페이지. 비나래아카이브의 시작점이에요.</div>
410 </div>
411 </a>
412 <a href="/hinana/index" class="service-item">
413 <div class="service-icon"><i class="bi bi-archive"></i></div>
414 <div>
415 <div class="service-name">비나래아카이브</div>
416 <div class="service-desc">비나래씨의 SNS이자 모두의 SNS. 일상과 생각을 기록하는 아카이브 공간이에요.</div>
417 </div>
418 </a>
419 <a href="/hinana/info" class="service-item">
420 <div class="service-icon"><i class="bi bi-person-circle"></i></div>
421 <div>
422 <div class="service-name">비나래씨란?</div>
423 <div class="service-desc">비나래씨에 대해 알아볼 수 있는 소개 페이지예요.</div>
424 </div>
425 </a>
426 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
427 <a href="/hinana/personal-notes" class="service-item">
428 <div class="service-icon"><i class="bi bi-journal"></i></div>
429 <div>
430 <div class="service-name">개인 노트</div>
431 <div class="service-desc">비나래씨만 사용하는 개인 노트 공간이에요.</div>
432 </div>
433 </a>
434 <% } %>
435 </div>
436 </div>
437 </div>
438 </div>
439
440 <!-- 비나래아카이브 도서관 모달 -->
441 <div class="modal fade gallery-modal" id="libraryModal" tabindex="-1">
442 <div class="modal-dialog modal-dialog-centered">
443 <div class="modal-content">
444 <div class="modal-header">
445 <h6 class="modal-title fw-bold">비나래아카이브 도서관</h6>
446 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
447 </div>
448 <div class="modal-body">
449 <a href="/hinana/blog" class="service-item">
450 <div class="service-icon"><i class="bi bi-book"></i></div>
451 <div>
452 <div class="service-name">비나래아카이브 도서관</div>
453 <div class="service-desc">비나래씨의 블로그. 긴 글과 이야기를 담아두는 도서관이에요.</div>
454 </div>
455 </a>
456 </div>
457 </div>
458 </div>
459 </div>
460
461 <!-- 비나래 라운지 모달 -->
462 <div class="modal fade gallery-modal" id="loungeModal" tabindex="-1">
463 <div class="modal-dialog modal-dialog-centered">
464 <div class="modal-content">
465 <div class="modal-header">
466 <h6 class="modal-title fw-bold">비나래 라운지</h6>
467 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
468 </div>
469 <div class="modal-body">
470 <a href="/hinana/lounge" class="service-item">
471 <div class="service-icon"><i class="bi bi-cup-hot"></i></div>
472 <div>
473 <div class="service-name">비나래 라운지</div>
474 <div class="service-desc">아카이브를 나와 라운지로. 다양한 기능들의 허브예요.</div>
475 </div>
476 </a>
477 <a href="/hinana/plaza" class="service-item">
478 <div class="service-icon"><i class="bi bi-chat-dots"></i></div>
479 <div>
480 <div class="service-name">비나래 광장</div>
481 <div class="service-desc">24시간 동안 유지되는 실시간 광장. 자유롭게 이야기해요.</div>
482 </div>
483 </a>
484 <a href="/hinana/gallery" class="service-item">
485 <div class="service-icon"><i class="bi bi-palette"></i></div>
486 <div>
487 <div class="service-name">라운지 갤러리</div>
488 <div class="service-desc">비나래씨의 디자인과 서비스들을 전시하는 갤러리예요.</div>
489 </div>
490 </a>
491 <a href="/hinana/tetris" class="service-item">
492 <div class="service-icon"><i class="bi bi-controller"></i></div>
493 <div>
494 <div class="service-name">TETRIS</div>
495 <div class="service-desc">라운지에서 즐기는 테트리스 게임이에요.</div>
496 </div>
497 </a>
498 <a href="/hinana/shop" class="service-item">
499 <div class="service-icon"><i class="bi bi-bookmark-star"></i></div>
500 <div>
501 <div class="service-name">책갈피 교환소</div>
502 <div class="service-desc">책갈피로 다양한 커스텀 아이템을 구매할 수 있어요.</div>
503 </div>
504 </a>
505 <a href="/hinana/image" class="service-item">
506 <div class="service-icon"><i class="bi bi-image"></i></div>
507 <div>
508 <div class="service-name">이미지 편집기</div>
509 <div class="service-desc">이미지를 불러와 원하는 위치에 텍스트를 추가하고 저장할 수 있어요.</div>
510 </div>
511 </a>
512 <a href="/hinana/exhibition" class="service-item">
513 <div class="service-icon"><i class="bi bi-easel2"></i></div>
514 <div>
515 <div class="service-name">특별전 <span style="font-size:0.7em; opacity:0.6;">Claude Design 테스트</span></div>
516 <div class="service-desc">Claude Design으로 제작한 미술관 스타일의 갤러리 특별전시입니다.</div>
517 </div>
518 </a>
519 <a href="/hinana/echo" class="service-item">
520 <div class="service-icon"><i class="bi bi-soundwave"></i></div>
521 <div>
522 <div class="service-name">에코 스튜디오</div>
523 <div class="service-desc">음악 파일에 노래방 스타일 에코 효과를 입혀 저장할 수 있어요.</div>
524 </div>
525 </a>
526 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
527 <div class="service-icon"><i class="bi bi-calculator"></i></div>
528 <div>
529 <div class="service-name">AI 토큰 계산기</div>
530 <div class="service-desc">GPT-5.5 기준으로 텍스트의 토큰 수와 예상 비용을 계산합니다.</div>
531 </div>
532 </a>
533 <a href="/hinana/subway" class="service-item">
534 <div class="service-icon"><i class="bi bi-train-front"></i></div>
535 <div>
536 <div class="service-name">열차 위치 조회</div>
537 <div class="service-desc">서울시 지하철 API로 열번의 현재 위치와 진입·도착·출발 상태를 확인합니다.</div>
538 </div>
539 </a>
540 </div>
541 </div>
542 </div>
543 </div>
544
545 <!-- 비나래아카이브 철도국 모달 -->
546 <footer class="site-footer">
547 <div class="footer-brand">
548 <img src="/image/sign.png" alt="비나래" class="footer-logo">
549 <div>
550 <div class="footer-title">비나래 라운지</div>
551 <div>Archive My Lounge</div>
552 </div>
553 </div>
554 <div>
555 <div class="footer-links">
556 <a href="/hinana/index">Archive</a>
557 <a href="/hinana/lounge">Lounge</a>
558 <a href="/hinana/gallery">Gallery</a>
559 <a href="/hinana/plaza">Plaza</a>
560 <a href="https://x.com/NoctchillHinana" target="_blank" rel="noreferrer">X</a>
561 </div>
562 <div class="footer-copy"><span class="footer-version">Ver. 8.0.3.2-Utsumi Aoba</span>ⓒ 2024~2026. 비나래 | hinana.moe</div>
563 </div>
564 </footer>
565
566 <div class="modal fade gallery-modal" id="railwayModal" tabindex="-1">
567 <div class="modal-dialog modal-dialog-centered">
568 <div class="modal-content">
569 <div class="modal-header">
570 <h6 class="modal-title fw-bold">비나래아카이브 철도국</h6>
571 <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
572 </div>
573 <div class="modal-body">
574 <a href="/hinana/train" class="service-item">
575 <div class="service-icon"><i class="bi bi-train-front"></i></div>
576 <div>
577 <div class="service-name">특급 히나나호</div>
578 <div class="service-desc">비내리는 열차를 탑승하여 기차 소리를 들으며 여행해보세요.</div>
579 </div>
580 </a>
581 <a href="/hinana/kivotosExp" class="service-item">
582 <div class="service-icon"><i class="bi bi-train-lightrail-front"></i></div>
583 <div>
584 <div class="service-name">키보토스 광역급행철도</div>
585 <div class="service-desc">플랫폼에서 승객을 만나고 노조미 또는 히카리 특급을 탑승해보세요.</div>
586 </div>
587 </a>
588 <a href="/hinana/lcd" class="service-item">
589 <div class="service-icon"><i class="bi bi-display"></i></div>
590 <div>
591 <div class="service-name">키보토스광역급행철도 LCD</div>
592 <div class="service-desc">키보토스 광역급행철도 열차 내 LCD 안내판을 재현합니다.</div>
593 </div>
594 </a>
595 </div>
596 </div>
597 </div>
598 </div>
599
600 <script>if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/sw.js"); }</script>
601 </body>
602 </html>
603