--- a/onboarding.js
+++ b/onboarding.js
@@ -1,37 +1,355 @@
-// doany.ai workspace onboarding — current production JS
-
-function nextStep(stepNumber) {
-  // Hide all steps
-  document.querySelectorAll('.onboarding-step').forEach(function(el) {
-    el.classList.remove('active');
-  });
-
-  // Show target step
-  var target = document.getElementById('step-' + stepNumber);
-  if (target) {
-    target.classList.add('active');
-  }
-
-  // No validation before advancing
-  // No progress indicator update
-  // No analytics tracking
-  // No transition animation
-}
-
-// No form validation
-// No inline error messages
-// No loading state when submitting
-// No error handling for failed API calls
-// No keyboard navigation support
-// No screen reader announcements for step changes
-
-// Signup form "submit" — no actual validation
-document.getElementById('signup-form').addEventListener('submit', function(e) {
-  e.preventDefault();
-  nextStep(2);
-});
-
-// No empty state enhancement
-// No skeleton loading screens
-// No retry logic for network failures
-// No timeout handling
+// doany.ai — Onboarding Controller
+// Handles: step navigation, validation, loading/error states, accessibility
+
+(function () {
+  'use strict';
+
+  var currentStep = 1;
+  var totalSteps = 3;
+
+  // ============================================
+  // STEP NAVIGATION
+  // ============================================
+
+  window.goToStep = function (stepNumber) {
+    if (stepNumber < 1 || stepNumber > totalSteps) return;
+
+    // Hide all steps
+    document.querySelectorAll('.onboarding-step').forEach(function (el) {
+      el.classList.remove('active');
+    });
+
+    // Show target
+    var target = document.getElementById('step-' + stepNumber);
+    if (target) {
+      target.classList.add('active');
+      // Focus the heading for screen readers
+      var heading = target.querySelector('h1');
+      if (heading) heading.focus();
+    }
+
+    currentStep = stepNumber;
+    updateProgress();
+    announceStep(stepNumber);
+  };
+
+  function showSection(id) {
+    document.querySelectorAll('.onboarding-step').forEach(function (el) {
+      el.classList.remove('active');
+    });
+    var el = document.getElementById(id);
+    if (el) el.classList.add('active');
+  }
+
+  // ============================================
+  // PROGRESS BAR
+  // ============================================
+
+  function updateProgress() {
+    document.querySelectorAll('.progress-step').forEach(function (step) {
+      var num = parseInt(step.getAttribute('data-step'), 10);
+      step.classList.remove('active', 'completed');
+      step.querySelector('.progress-dot').removeAttribute('aria-current');
+
+      if (num < currentStep) {
+        step.classList.add('completed');
+      } else if (num === currentStep) {
+        step.classList.add('active');
+        step.querySelector('.progress-dot').setAttribute('aria-current', 'step');
+      }
+    });
+  }
+
+  // ============================================
+  // SCREEN READER ANNOUNCEMENTS
+  // ============================================
+
+  function announceStep(stepNumber) {
+    var labels = {
+      1: 'Step 1 of 3: Create your account',
+      2: 'Step 2 of 3: Set up your workspace',
+      3: 'Step 3 of 3: Invite your team'
+    };
+    var region = document.getElementById('sr-announce');
+    if (region && labels[stepNumber]) {
+      region.textContent = labels[stepNumber];
+    }
+  }
+
+  // ============================================
+  // VALIDATION
+  // ============================================
+
+  function validateEmail(email) {
+    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
+  }
+
+  function showFieldError(inputId, errorId) {
+    var input = document.getElementById(inputId);
+    var error = document.getElementById(errorId);
+    if (input) input.classList.add('error');
+    if (error) error.classList.add('visible');
+  }
+
+  function clearFieldError(inputId, errorId) {
+    var input = document.getElementById(inputId);
+    var error = document.getElementById(errorId);
+    if (input) input.classList.remove('error');
+    if (error) error.classList.remove('visible');
+  }
+
+  function clearAllErrors(formEl) {
+    formEl.querySelectorAll('.form-input, .form-select, .form-textarea').forEach(function (el) {
+      el.classList.remove('error');
+    });
+    formEl.querySelectorAll('.form-error').forEach(function (el) {
+      el.classList.remove('visible');
+    });
+  }
+
+  // Real-time validation: clear error on input
+  document.querySelectorAll('.form-input, .form-textarea').forEach(function (input) {
+    input.addEventListener('input', function () {
+      input.classList.remove('error');
+      var errorEl = input.getAttribute('aria-describedby');
+      if (errorEl) {
+        var err = document.getElementById(errorEl);
+        if (err) err.classList.remove('visible');
+      }
+    });
+  });
+
+  // ============================================
+  // LOADING STATE
+  // ============================================
+
+  function setLoading(btnId, isLoading) {
+    var btn = document.getElementById(btnId);
+    if (!btn) return;
+    if (isLoading) {
+      btn.classList.add('loading');
+      btn.disabled = true;
+      btn.setAttribute('aria-busy', 'true');
+    } else {
+      btn.classList.remove('loading');
+      btn.disabled = false;
+      btn.removeAttribute('aria-busy');
+    }
+  }
+
+  // Simulate async API call
+  function simulateAPI(duration) {
+    return new Promise(function (resolve) {
+      setTimeout(resolve, duration || 1200);
+    });
+  }
+
+  // ============================================
+  // ERROR BANNER
+  // ============================================
+
+  function showError(bannerId, message) {
+    var banner = document.getElementById(bannerId);
+    if (!banner) return;
+    if (message) {
+      banner.querySelector('.error-banner-text').textContent = message;
+    }
+    banner.classList.add('visible');
+  }
+
+  window.dismissError = function (bannerId) {
+    var banner = document.getElementById(bannerId);
+    if (banner) banner.classList.remove('visible');
+  };
+
+  // ============================================
+  // STEP 1: SIGN UP
+  // ============================================
+
+  document.getElementById('signup-form').addEventListener('submit', function (e) {
+    e.preventDefault();
+    var form = this;
+    clearAllErrors(form);
+
+    var email = document.getElementById('email');
+    var password = document.getElementById('password');
+    var terms = document.getElementById('terms');
+    var valid = true;
+
+    if (!email.value.trim() || !validateEmail(email.value.trim())) {
+      showFieldError('email', 'email-error');
+      valid = false;
+    }
+
+    if (!password.value || password.value.length < 8) {
+      showFieldError('password', 'password-error');
+      valid = false;
+    }
+
+    if (!terms.checked) {
+      document.getElementById('terms-error').classList.add('visible');
+      valid = false;
+    }
+
+    if (!valid) return;
+
+    setLoading('signup-btn', true);
+
+    simulateAPI(1400).then(function () {
+      setLoading('signup-btn', false);
+      goToStep(2);
+
+      // Auto-generate workspace URL from email domain
+      var domain = email.value.split('@')[1];
+      if (domain) {
+        var slug = domain.split('.')[0].toLowerCase();
+        var urlInput = document.getElementById('workspace-url');
+        var nameInput = document.getElementById('workspace-name');
+        if (urlInput && !urlInput.value) urlInput.value = slug;
+        if (nameInput && !nameInput.value) {
+          nameInput.value = slug.charAt(0).toUpperCase() + slug.slice(1);
+        }
+      }
+    });
+  });
+
+  // ============================================
+  // STEP 2: WORKSPACE
+  // ============================================
+
+  document.getElementById('workspace-form').addEventListener('submit', function (e) {
+    e.preventDefault();
+    var form = this;
+    clearAllErrors(form);
+
+    var name = document.getElementById('workspace-name');
+    var url = document.getElementById('workspace-url');
+    var valid = true;
+
+    if (!name.value.trim()) {
+      showFieldError('workspace-name', 'workspace-name-error');
+      valid = false;
+    }
+
+    if (!url.value.trim()) {
+      showFieldError('workspace-url', 'workspace-url-error');
+      valid = false;
+    }
+
+    if (!valid) return;
+
+    setLoading('workspace-btn', true);
+
+    simulateAPI(1000).then(function () {
+      setLoading('workspace-btn', false);
+      goToStep(3);
+    });
+  });
+
+  // Auto-slugify workspace name -> URL
+  document.getElementById('workspace-name').addEventListener('input', function () {
+    var slug = this.value
+      .toLowerCase()
+      .replace(/[^a-z0-9]+/g, '-')
+      .replace(/^-|-$/g, '');
+    document.getElementById('workspace-url').value = slug;
+  });
+
+  // ============================================
+  // STEP 3: INVITES
+  // ============================================
+
+  document.getElementById('invite-form').addEventListener('submit', function (e) {
+    e.preventDefault();
+
+    var textarea = document.getElementById('invite-emails');
+    var emails = textarea.value.trim();
+
+    // If empty, just finish
+    if (!emails) {
+      finishOnboarding();
+      return;
+    }
+
+    setLoading('invite-btn', true);
+
+    simulateAPI(1500).then(function () {
+      setLoading('invite-btn', false);
+      finishOnboarding();
+    });
+  });
+
+  window.finishOnboarding = function () {
+    // Mark all progress steps completed
+    document.querySelectorAll('.progress-step').forEach(function (step) {
+      step.classList.remove('active');
+      step.classList.add('completed');
+      step.querySelector('.progress-dot').removeAttribute('aria-current');
+    });
+
+    showSection('step-success');
+
+    var region = document.getElementById('sr-announce');
+    if (region) region.textContent = 'Onboarding complete. Your workspace is ready.';
+
+    // Focus the success heading
+    var heading = document.getElementById('success-heading');
+    if (heading) heading.focus();
+  };
+
+  // ============================================
+  // DASHBOARD / EMPTY STATE
+  // ============================================
+
+  window.goToDashboard = function () {
+    // Hide progress bar
+    var progress = document.querySelector('.progress-bar');
+    if (progress) progress.style.display = 'none';
+
+    showSection('empty-state');
+
+    var heading = document.getElementById('empty-heading');
+    if (heading) heading.focus();
+
+    var region = document.getElementById('sr-announce');
+    if (region) region.textContent = 'Dashboard. No projects yet.';
+  };
+
+  window.createProject = function () {
+    // Placeholder — would open project creation flow
+    alert('Project creation flow would open here.');
+  };
+
+  // ============================================
+  // PASSWORD TOGGLE
+  // ============================================
+
+  window.togglePassword = function () {
+    var input = document.getElementById('password');
+    var toggle = document.querySelector('.password-toggle');
+    if (!input || !toggle) return;
+
+    if (input.type === 'password') {
+      input.type = 'text';
+      toggle.textContent = 'Hide';
+      toggle.setAttribute('aria-label', 'Hide password');
+    } else {
+      input.type = 'password';
+      toggle.textContent = 'Show';
+      toggle.setAttribute('aria-label', 'Show password');
+    }
+  };
+
+  // ============================================
+  // INIT
+  // ============================================
+
+  // Focus visible headings for tab navigation
+  document.querySelectorAll('.step-heading, .success-heading, .empty-heading').forEach(function (el) {
+    el.setAttribute('tabindex', '-1');
+  });
+
+  // Initialize progress bar
+  updateProgress();
+  announceStep(1);
+})();
