mirror of
https://github.com/headporter81/specialsource-homepage-frontend.git
synced 2026-08-08 15:21:11 +09:00
This commit is contained in:
+26
-35
@@ -170,12 +170,10 @@ const loginPw = ref('');
|
||||
const activeMenu = ref('main');
|
||||
const authToken = ref(localStorage.getItem('token'));
|
||||
|
||||
// 글로벌 오버레이 레이어 상태 관리 변수
|
||||
const isProcessing = ref(false);
|
||||
const overlayProgress = ref(0);
|
||||
const overlayStatus = ref('');
|
||||
|
||||
// 메뉴 아이템 배열
|
||||
const menuItems = [
|
||||
{ id: 'main', name: 'HOME' },
|
||||
{ id: 'youtube', name: 'YOUTUBE' },
|
||||
@@ -186,12 +184,9 @@ const menuItems = [
|
||||
|
||||
const isLoggedIn = computed(() => !!authToken.value);
|
||||
|
||||
// 🟢 [UPGRADE] 메뉴 이동 시 영화 같은 TUI 로딩바 시퀀스 구동
|
||||
const changeMenu = (id) => {
|
||||
// 이미 열려있는 메뉴를 다시 누르면 불필요한 시퀀스 방지 차단
|
||||
if (activeMenu.value === id) return;
|
||||
|
||||
// 1) 즉시 화면 전체를 덮고 초기 세팅
|
||||
isProcessing.value = true;
|
||||
overlayProgress.value = 0;
|
||||
overlayStatus.value = `INITIALIZING ROUTE ACCESS: /${id.toUpperCase()}...`;
|
||||
@@ -200,11 +195,9 @@ const changeMenu = (id) => {
|
||||
termInstance.value.echo(`\n[[b;green;]>] NAVIGATING TO /${id.toUpperCase()}... INITIALIZING PIPELINE.`);
|
||||
}
|
||||
|
||||
// 2) 400ms 동안 빠르게 게이지를 채우는 인터벌 구동 (속도 체감 굿)
|
||||
const interval = setInterval(() => {
|
||||
overlayProgress.value += 5;
|
||||
|
||||
// 진행 수치별 리눅스 해커 감성 문구 전환
|
||||
if (overlayProgress.value === 25) {
|
||||
overlayStatus.value = `ALLOCATING MEMORY BUFFER FOR VUE_COMPONENT...`;
|
||||
}
|
||||
@@ -212,12 +205,10 @@ const changeMenu = (id) => {
|
||||
overlayStatus.value = `DECRYPTING INTERFACE LOGS & SECURE ASSETS...`;
|
||||
}
|
||||
if (overlayProgress.value === 85) {
|
||||
// ★ 85% 지점 오버레이 베일 뒤에서 슥 메인 콘텐츠 메뉴를 스왑!
|
||||
activeMenu.value = id;
|
||||
overlayStatus.value = `MOUNTING VIRTUAL DOM TREE... SUCCESS.`;
|
||||
}
|
||||
|
||||
// 100% 도달 완료 시 종료 세팅
|
||||
if (overlayProgress.value >= 100) {
|
||||
clearInterval(interval);
|
||||
|
||||
@@ -225,15 +216,13 @@ const changeMenu = (id) => {
|
||||
termInstance.value.echo(`[[b;green;][SUCCESS]] COMPONENT LOADED PERFECTLY.`);
|
||||
}
|
||||
|
||||
// 여운을 약간 준 뒤 부드럽게 창 닫기
|
||||
setTimeout(() => {
|
||||
isProcessing.value = false;
|
||||
}, 120);
|
||||
}
|
||||
}, 20); // 20ms * 20단계 = 총 400ms 로딩 스피드 보장
|
||||
}, 20);
|
||||
};
|
||||
|
||||
// 로그인 등 다른 비즈니스 로직에서 사용하는 동적 제어용 스크립트는 원본 유지
|
||||
const triggerOverlayProcess = (durationMs, initialMsg) => {
|
||||
isProcessing.value = true;
|
||||
overlayProgress.value = 0;
|
||||
@@ -361,17 +350,26 @@ onMounted(() => {
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@500;700&display=swap');
|
||||
|
||||
/* GNB, 버튼, 인풋, 아스키, 터미널까지 싹 다 개발자 폰트로 대통합 */
|
||||
/* GNB, 버튼, 인풋, 터미널 등 일반 텍스트 영역은 개발자 폰트 대통합 */
|
||||
.homepage-wrapper,
|
||||
.menu-btn,
|
||||
.nav-item,
|
||||
.ascii-art,
|
||||
.terminal-box,
|
||||
.tui-global-overlay,
|
||||
.login-terminal-frame,
|
||||
.project-item,
|
||||
.about-text,
|
||||
.contact-form,
|
||||
:deep(.terminal),
|
||||
:deep(.terminal span) {
|
||||
font-family: 'JetBrains Mono', monospace !important;
|
||||
}
|
||||
|
||||
/* 🌟 [핵심 수정] 웹 폰트(JetBrains) 서브셋에서 특수문자 선 기호(╔, ═, ╝)가 빠지는 버그 차단.
|
||||
배너 영역만큼은 모바일 크롬 내장 순수 모노스페이스 스택으로 완전 분리하여 1:1 완벽 정렬 강제 유도 */
|
||||
.ascii-art {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
@@ -395,7 +393,7 @@ onMounted(() => {
|
||||
.nav-menu { display: flex; gap: 20px; }
|
||||
.menu-btn {
|
||||
background: none; border: none; color: #008800;
|
||||
font-family: monospace; font-size: 16px; cursor: pointer;
|
||||
font-size: 16px; cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
.menu-btn:hover, .menu-btn.active { color: #00ff00; text-shadow: 0 0 10px #00ff00; }
|
||||
@@ -410,7 +408,6 @@ onMounted(() => {
|
||||
padding: 6px 18px;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 13px;
|
||||
box-shadow: 0 0 5px rgba(0, 255, 0, 0.3);
|
||||
transition: 0.3s;
|
||||
@@ -420,7 +417,7 @@ onMounted(() => {
|
||||
color: #00ff00 !important;
|
||||
box-shadow: 0 0 10px #00ff00;
|
||||
}
|
||||
.user-info { color: #008800 !important; font-size: 12px; margin-right: 15px; font-family: monospace; letter-spacing: 1px;}
|
||||
.user-info { color: #008800 !important; font-size: 12px; margin-right: 15px; letter-spacing: 1px;}
|
||||
.status-dot { width: 8px; height: 8px; background: #ff3b3b; border-radius: 50%; box-shadow: 0 0 8px #ff3b3b; transition: 0.5s; }
|
||||
.status-dot.secure-mode { background: #00ff00; box-shadow: 0 0 8px #00ff00; }
|
||||
|
||||
@@ -432,7 +429,7 @@ onMounted(() => {
|
||||
flex-direction: column;
|
||||
}
|
||||
.sub-page { max-width: 1000px; margin: 0 auto; padding-top: 15px; width: 100%; }
|
||||
.page-title { font-family: monospace; border-bottom: 1px solid #113311; padding-bottom: 10px; margin-bottom: 20px; color: #00ff00;}
|
||||
.page-title { border-bottom: 1px solid #113311; padding-bottom: 10px; margin-bottom: 20px; color: #00ff00;}
|
||||
|
||||
/* 메인 홈 아스키 전광판 레이아웃 */
|
||||
.main-page {
|
||||
@@ -443,7 +440,6 @@ onMounted(() => {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 글로벌 오버레이 배경 암전 처리 레이어 CSS 스타일 */
|
||||
.tui-global-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -466,8 +462,6 @@ onMounted(() => {
|
||||
position: relative;
|
||||
}
|
||||
.ascii-art {
|
||||
/* 🟢 [★변경] 시스템 폰트 대신, 다운로드한 정밀 고정폭 폰트를 최우선 적용 */
|
||||
font-family: 'JetBrains Mono', monospace !important;
|
||||
font-weight: bold;
|
||||
white-space: pre;
|
||||
display: block;
|
||||
@@ -514,7 +508,6 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
max-width: 550px; margin: 40px auto;
|
||||
border: 1px dashed #00ff00; padding: 35px;
|
||||
background: #020a02; box-shadow: 0 0 15px rgba(0, 255, 0, 0.1);
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
}
|
||||
.login-gate-title { color: #00ff00; font-size: 20px; margin-bottom: 10px; font-weight: bold;}
|
||||
.login-gate-desc { color: #008800; font-size: 12px; margin-bottom: 30px; line-height: 1.4; }
|
||||
@@ -523,21 +516,21 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
.login-label { width: 120px; color: #00ff00; font-weight: bold; font-size: 14px; }
|
||||
.login-input {
|
||||
flex: 1; background: none; border: none; color: #00ff00;
|
||||
font-family: 'Courier New', Courier, monospace; font-size: 15px; outline: none;
|
||||
font-size: 15px; outline: none;
|
||||
}
|
||||
.login-submit-btn {
|
||||
margin-top: 15px; background: none; border: 1px solid #00ff00;
|
||||
color: #00ff00; padding: 12px; font-family: 'Courier New', Courier, monospace;
|
||||
color: #00ff00; padding: 12px;
|
||||
font-size: 14px; font-weight: bold; cursor: pointer; transition: 0.3s;
|
||||
}
|
||||
.login-submit-btn:hover { background: #00ff00; color: #000; box-shadow: 0 0 15px #00ff00; }
|
||||
|
||||
/* 프로젝트 리스트 */
|
||||
.project-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
|
||||
.project-item { border: 1px solid #113311; padding: 15px; background: #080808; font-family: monospace;}
|
||||
.project-item { border: 1px solid #113311; padding: 15px; background: #080808; }
|
||||
.item-header { font-weight: bold; margin-bottom: 10px; color: #00ff00; }
|
||||
.about-text { font-family: monospace; line-height: 2; color: #00cc00;}
|
||||
.contact-form { font-family: monospace; line-height: 2; color: #00cc00;}
|
||||
.about-text { line-height: 2; color: #00cc00;}
|
||||
.contact-form { line-height: 2; color: #00cc00;}
|
||||
|
||||
/* 애니메이션 트랜지션 */
|
||||
.fade-enter-active, .fade-leave-active { transition: opacity 0.25s ease; }
|
||||
@@ -548,7 +541,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
height: 300px; margin: 10px 40px 30px;
|
||||
border: 2px solid #1a1a1a; background: #0a0a0a; overflow: hidden;
|
||||
}
|
||||
.monitor-header { background: #151515; padding: 5px 15px; color: #555; display: flex; justify-content: space-between; font-family: monospace; font-size: 12px;}
|
||||
.monitor-header { background: #151515; padding: 5px 15px; color: #555; display: flex; justify-content: space-between; font-size: 12px;}
|
||||
.monitor-status { color: #00aa00; animation: blink 2s infinite; }
|
||||
.crt-screen-overlay { position: relative; height: calc(100% - 30px); background: #020802; }
|
||||
.crt-screen-overlay::before {
|
||||
@@ -559,11 +552,10 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
.terminal-box { width: 100%; height: 100%; padding: 10px; }
|
||||
|
||||
:deep(.terminal), :deep(.terminal span) {
|
||||
--color: #33ff33 !important; font-family: monospace !important;
|
||||
--color: #33ff33 !important;
|
||||
text-shadow: 0 0 5px rgba(51, 255, 51, 0.6) !important;
|
||||
}
|
||||
|
||||
/* 📱 반응형 분기점 */
|
||||
/* 📱 반응형 분기점 */
|
||||
@media screen and (max-width: 1100px) {
|
||||
#videos-container { grid-template-columns: repeat(2, 1fr); }
|
||||
@@ -574,7 +566,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
.project-grid { grid-template-columns: 1fr; }
|
||||
.auth-nav { flex-direction: column; gap: 12px; padding: 15px 20px; }
|
||||
|
||||
/* 유저님이 원하셨던 모바일 가로 스크롤 완벽 보장 설정 */
|
||||
/* 🟢 [가로 스크롤 활성화] 원래 원하셨던 모바일 가로 스크롤 컨테이너 복구 */
|
||||
.ascii-container {
|
||||
width: 100%;
|
||||
overflow-x: auto !important;
|
||||
@@ -586,20 +578,19 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
|
||||
}
|
||||
|
||||
.ascii-art {
|
||||
font-size: 11px !important; /* 모바일 가로 스크롤 가독성 최적 크기 */
|
||||
line-height: 1.3 !important;
|
||||
font-size: 10px !important; /* 가로 스크롤 시 한눈에 잡히는 모바일 최적 크기 */
|
||||
line-height: 1.35 !important;
|
||||
white-space: pre !important;
|
||||
word-break: keep-all !important;
|
||||
width: max-content !important;
|
||||
margin: 0 !important;
|
||||
|
||||
/* 갤럭시용 폰트 부스팅 버그 방어 */
|
||||
/* 🟢 [치트키] 모바일 크롬이 글자 크기를 강제 보정해서 칼각을 찢어버리는 '폰트 부스팅' 버그 완벽 차단 */
|
||||
-webkit-text-size-adjust: none !important;
|
||||
text-size-adjust: none !important;
|
||||
max-height: 999999px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
|
||||
|
||||
/* 일회성 사이버 글리치 키프레임 */
|
||||
|
||||
Reference in New Issue
Block a user