diff --git a/src/style.css b/src/style.css index 1050b5d..cb052ca 100644 --- a/src/style.css +++ b/src/style.css @@ -160,7 +160,8 @@ body, html { margin: 0; padding: 0; width: 100%; height: 100%; background-color: .status-dot.secure-mode { background: var(--tui-color); box-shadow: 0 0 8px var(--tui-color); } /* --- 컨텐츠 영역 --- */ -.content-area { flex: 1; padding: 8px 20px; min-height: 220px; overflow-y: auto; display: flex; flex-direction: column; } +.content-area { flex: 1 1 auto; padding: 8px 20px; min-height: 220px; overflow-y: auto; display: flex; flex-direction: column; transition: flex-grow 0.6s ease; } +.homepage-wrapper.intro-done .content-area { flex-grow: 0; } .sub-page { max-width: 1000px; margin: 0 auto; padding-top: 15px; width: 100%; } .page-title { border-bottom: 1px solid var(--tui-border); padding-bottom: 10px; margin-bottom: 20px; color: var(--tui-color);} @@ -172,7 +173,11 @@ body, html { margin: 0; padding: 0; width: 100%; height: 100%; background-color: justify-content: center; align-items: center; pointer-events: all; } -.ascii-container { width: 100%; overflow-x: auto; overflow-y: hidden; padding: 6px 20px; box-sizing: border-box; position: relative; } +.ascii-container { + width: 100%; overflow-x: auto; overflow-y: hidden; padding: 6px 20px; box-sizing: border-box; position: relative; + max-height: 600px; opacity: 1; transition: max-height 0.6s ease, opacity 0.5s ease, padding 0.6s ease; +} +.ascii-container.is-collapsed { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; } .ascii-clip { width: max-content; margin: 0 auto; overflow: hidden; } .ascii-art { font-weight: bold; white-space: pre; display: block; margin: 0 auto; width: max-content; @@ -258,6 +263,27 @@ iframe { width: 100%; height: 180px; border-radius: 4px; } } .terminal-box { width: 100%; height: 100%; padding: 10px; box-sizing: border-box; } +/* ============================================================== + 부팅 로그 스크린 (초기 진입 시 로그 출력 후 사라짐) + ============================================================== */ +.boot-log-screen { + position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; + background-color: #000; z-index: 10000; display: flex; + justify-content: center; align-items: center; pointer-events: all; +} +.boot-log-box { + width: 100%; max-width: 620px; padding: 0 20px; box-sizing: border-box; + font-family: 'JetBrains Mono', monospace; +} +.boot-log-line { + margin: 0 0 6px; font-size: 13px; color: var(--tui-color); + text-shadow: 0 0 5px var(--tui-glow); letter-spacing: 0.5px; + animation: bootLineIn 0.2s ease-out; +} +.boot-cursor { + color: var(--tui-color); font-size: 14px; animation: blink 1s infinite; +} + /* ============================================================== 진행률 바 (TuiProgressBar.vue) ============================================================== */ @@ -481,6 +507,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; } @keyframes textPulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; text-shadow: 0 0 8px var(--tui-glow); } } @keyframes badgeBlink { 0%, 100% { opacity: 0.6; box-shadow: 0 0 5px rgba(255, 59, 59, 0.2); } 50% { opacity: 1; box-shadow: 0 0 15px rgba(255, 59, 59, 0.6); text-shadow: 0 0 12px #ff3b3b; } } @keyframes dashReveal { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } +@keyframes bootLineIn { from { opacity: 0; transform: translateX(-4px); } to { opacity: 1; transform: translateX(0); } } @keyframes once-cyber-glitch-wobble { 0%, 25% { transform: translate(0) scale(1) skewX(0deg); color: var(--tui-color) !important; text-shadow: 0 0 8px var(--tui-glow) !important; opacity: 1; } 26% { transform: translate(-3px, 1.5px) scale(1.02); color: #ffffff !important; text-shadow: 2px 0 #ff0000, -2px 0 #0000ff !important; } diff --git a/src/views/Main.vue b/src/views/Main.vue index b049f81..1d5705b 100644 --- a/src/views/Main.vue +++ b/src/views/Main.vue @@ -1,5 +1,5 @@ @@ -217,6 +233,36 @@ const isProcessing = ref(false); const overlayProgress = ref(0); const overlayStatus = ref(''); +const isBooting = ref(true); +const logoDone = ref(false); +const bootLines = ref([]); +const BOOT_SEQUENCE = [ + '[SYS] SPECIALSOURCE.SYSTEM BIOS V3.2', + '[SYS] PERFORMING MEMORY CHECK... OK', + '[SYS] INITIALIZING KERNEL MODULES...', + '[SYS] MOUNTING VIRTUAL FILESYSTEM... OK', + '[SYS] ESTABLISHING SECURE NETWORK LINK...', + '[SYS] LOADING DASHBOARD INTERFACE...', + '[SYS] SPAWNING TERMINAL CONSOLE...', + '[SUCCESS] BOOT SEQUENCE COMPLETE.' +]; + +const runBootSequence = () => { + let i = 0; + const pushLine = () => { + if (i < BOOT_SEQUENCE.length) { + bootLines.value.push(BOOT_SEQUENCE[i]); + i++; + setTimeout(pushLine, 220); + } else { + setTimeout(() => { + isBooting.value = false; + }, 500); + } + }; + pushLine(); +}; + const systemAlert = ref({ show: false, message: '' }); const showSystemAlert = (message) => { systemAlert.value = { show: true, message }; @@ -449,6 +495,8 @@ const handleLoginSubmit = async () => { }; onMounted(() => { + runBootSequence(); + fetchVideos(); fetchAnalyticsData();