// ============================================================ // THE BEACON - Tutorial / Onboarding // First-time player walkthrough (4 screens + skip option) // ============================================================ const TUTORIAL_KEY = 'the-beacon-tutorial-done'; const TUTORIAL_STEPS = [ { title: 'THE BEACON', body: 'Build an AI from scratch.\n\nWrite code. Train models. Deploy to the world.\nSave lives.', icon: '🏠', tip: 'A sovereign AI idle game' }, { title: 'WRITE CODE', body: 'Click WRITE CODE or press SPACE to generate code.\n\nClick fast for combo bonuses:\n 10× combo → bonus ops\n 20× combo → bonus knowledge\n 30×+ combo → bonus code', icon: '⌨️', tip: 'This is your primary action' }, { title: 'BUILD & RESEARCH', body: 'Buy Buildings for passive production.\nThey generate resources automatically.\n\nResearch Projects appear as you progress.\nThey unlock powerful multipliers and new systems.', icon: '🏗️', tip: 'Automation is the goal' }, { title: 'PHASES & PROGRESS', body: 'The game has 6 phases, from "The First Line" to "The Beacon."\n\nEach phase unlocks new buildings, projects, and challenges.\n\nYour AI grows from a script... to something that matters.', icon: '📊', tip: 'Watch the progress bar at the top' }, { title: 'YOU\'RE READY', body: 'Buildings produce while you think.\nProjects multiply your output.\nKeep harmony high. Avoid the Drift.\n\nThe Beacon is waiting. Start writing.', icon: '✦', tip: 'Press ? anytime for keyboard shortcuts' } ]; function isTutorialDone() { try { return localStorage.getItem(TUTORIAL_KEY) === 'done'; } catch (e) { return true; // If localStorage is broken, skip tutorial } } function markTutorialDone() { try { localStorage.setItem(TUTORIAL_KEY, 'done'); } catch (e) { // silent fail } } function createTutorialStyles() { if (document.getElementById('tutorial-styles')) return; const style = document.createElement('style'); style.id = 'tutorial-styles'; style.textContent = ` #tutorial-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(8, 8, 16, 0.96); z-index: 300; display: flex; justify-content: center; align-items: center; animation: tutorial-fade-in 0.4s ease-out; } @keyframes tutorial-fade-in { from { opacity: 0 } to { opacity: 1 } } #tutorial-card { background: #0e0e1a; border: 1px solid #1a3a5a; border-radius: 10px; padding: 32px 36px; max-width: 420px; width: 90%; text-align: center; animation: tutorial-slide-up 0.5s ease-out; position: relative; } @keyframes tutorial-slide-up { from { transform: translateY(20px); opacity: 0 } to { transform: translateY(0); opacity: 1 } } #tutorial-card .t-icon { font-size: 36px; margin-bottom: 12px; display: block; } #tutorial-card .t-title { color: #4a9eff; font-size: 16px; font-weight: 700; letter-spacing: 3px; margin-bottom: 12px; font-family: inherit; } #tutorial-card .t-body { color: #999; font-size: 11px; line-height: 1.9; margin-bottom: 20px; white-space: pre-line; font-family: inherit; text-align: left; } #tutorial-card .t-tip { color: #555; font-size: 9px; font-style: italic; margin-bottom: 20px; letter-spacing: 1px; font-family: inherit; } #tutorial-dots { display: flex; gap: 6px; justify-content: center; margin-bottom: 18px; } #tutorial-dots .t-dot { width: 6px; height: 6px; border-radius: 50%; background: #1a1a2e; transition: background 0.3s; } #tutorial-dots .t-dot.active { background: #4a9eff; box-shadow: 0 0 6px rgba(74, 158, 255, 0.4); } #tutorial-btns { display: flex; gap: 8px; justify-content: center; } #tutorial-btns button { font-family: inherit; font-size: 11px; padding: 8px 20px; border-radius: 4px; cursor: pointer; transition: all 0.15s; } #tutorial-next-btn { background: #1a2a3a; border: 1px solid #4a9eff; color: #4a9eff; } #tutorial-next-btn:hover { background: #203040; box-shadow: 0 0 12px rgba(74, 158, 255, 0.2); } #tutorial-skip-btn { background: transparent; border: 1px solid #333; color: #555; } #tutorial-skip-btn:hover { border-color: #555; color: #888; } `; document.head.appendChild(style); } function renderTutorialStep(index) { const step = TUTORIAL_STEPS[index]; if (!step) return; let overlay = document.getElementById('tutorial-overlay'); if (!overlay) { overlay = document.createElement('div'); overlay.id = 'tutorial-overlay'; document.body.appendChild(overlay); } const isLast = index === TUTORIAL_STEPS.length - 1; // Build dots let dots = ''; for (let i = 0; i < TUTORIAL_STEPS.length; i++) { dots += `
`; } overlay.innerHTML = `
${step.icon}
${step.title}
${step.body}
${step.tip}
${dots}
`; // Focus the next button so Enter works const nextBtn = document.getElementById('tutorial-next-btn'); if (nextBtn) nextBtn.focus(); } let _tutorialStep = 0; function nextTutorialStep() { _tutorialStep++; renderTutorialStep(_tutorialStep); } // Keyboard support: Enter/Right to advance, Escape to close document.addEventListener('keydown', function tutorialKeyHandler(e) { if (!document.getElementById('tutorial-overlay')) return; if (e.key === 'Enter' || e.key === 'ArrowRight') { e.preventDefault(); if (_tutorialStep >= TUTORIAL_STEPS.length - 1) { closeTutorial(); } else { nextTutorialStep(); } } else if (e.key === 'Escape') { e.preventDefault(); closeTutorial(); } }); function closeTutorial() { const overlay = document.getElementById('tutorial-overlay'); if (overlay) { overlay.style.animation = 'tutorial-fade-in 0.3s ease-in reverse'; setTimeout(() => overlay.remove(), 280); } markTutorialDone(); } function startTutorial() { if (isTutorialDone()) return; createTutorialStyles(); _tutorialStep = 0; // Small delay so the page renders first setTimeout(() => renderTutorialStep(0), 300); }