diff --git a/journey.php b/journey.php
new file mode 100644
index 0000000..71e73a4
--- /dev/null
+++ b/journey.php
@@ -0,0 +1,64 @@
+
+
+
+
+User Journey | The Elements of Typographic Style Applied to the Web
+
+
+
+
+
+
+
+
+
User Journey
+
+
Create your own typographic journey by adding steps, inputs, and results. Each step represents a stage in your design process, helping you document and track your typography decisions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
No steps yet. Click "Add Step" to begin your journey.
+
+
+
+
+
+
About User Journeys
+
A user journey helps you:
+
+
Document your design process
+
Track typography decisions
+
Record inputs and outcomes
+
Share your workflow
+
+
+
How to Use
+
Add Step: Create a new step in your journey
+
Edit: Click on any field to edit it
+
Delete: Remove steps you no longer need
+
Export/Import: Save and share your journey
+
+
+
+
+
+
+
+
+
diff --git a/js/journey.js b/js/journey.js
new file mode 100644
index 0000000..57885fc
--- /dev/null
+++ b/js/journey.js
@@ -0,0 +1,359 @@
+// User Journey Management
+(function() {
+ 'use strict';
+
+ let journey = {
+ steps: []
+ };
+
+ const STORAGE_KEY = 'webtypography_journey';
+
+ // DOM Elements
+ const journeyContainer = document.getElementById('journey-container');
+ const emptyState = document.getElementById('journey-empty');
+ const addStepBtn = document.getElementById('add-step');
+ const clearJourneyBtn = document.getElementById('clear-journey');
+ const exportJourneyBtn = document.getElementById('export-journey');
+ const importJourneyBtn = document.getElementById('import-journey');
+
+ // Initialize
+ function init() {
+ loadJourney();
+ renderJourney();
+ attachEventListeners();
+ }
+
+ // Load journey from localStorage
+ function loadJourney() {
+ try {
+ const saved = localStorage.getItem(STORAGE_KEY);
+ if (saved) {
+ journey = JSON.parse(saved);
+ if (!Array.isArray(journey.steps)) {
+ journey.steps = [];
+ }
+ }
+ } catch (e) {
+ console.error('Error loading journey:', e);
+ journey.steps = [];
+ }
+ }
+
+ // Save journey to localStorage
+ function saveJourney() {
+ try {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(journey));
+ } catch (e) {
+ console.error('Error saving journey:', e);
+ alert('Error saving journey. Your browser storage may be full.');
+ }
+ }
+
+ // Attach event listeners
+ function attachEventListeners() {
+ addStepBtn.addEventListener('click', addStep);
+ clearJourneyBtn.addEventListener('click', clearJourney);
+ exportJourneyBtn.addEventListener('click', exportJourney);
+ importJourneyBtn.addEventListener('click', importJourney);
+ }
+
+ // Add a new step
+ function addStep() {
+ const newStep = {
+ id: Date.now(),
+ title: 'New Step',
+ input: '',
+ result: ''
+ };
+ journey.steps.push(newStep);
+ saveJourney();
+ renderJourney();
+ }
+
+ // Remove a step
+ function removeStep(id) {
+ if (confirm('Are you sure you want to delete this step?')) {
+ journey.steps = journey.steps.filter(step => step.id !== id);
+ saveJourney();
+ renderJourney();
+ }
+ }
+
+ // Move step up
+ function moveStepUp(id) {
+ const index = journey.steps.findIndex(step => step.id === id);
+ if (index > 0) {
+ [journey.steps[index - 1], journey.steps[index]] =
+ [journey.steps[index], journey.steps[index - 1]];
+ saveJourney();
+ renderJourney();
+ }
+ }
+
+ // Move step down
+ function moveStepDown(id) {
+ const index = journey.steps.findIndex(step => step.id === id);
+ if (index < journey.steps.length - 1) {
+ [journey.steps[index], journey.steps[index + 1]] =
+ [journey.steps[index + 1], journey.steps[index]];
+ saveJourney();
+ renderJourney();
+ }
+ }
+
+ // Update step field
+ function updateStep(id, field, value) {
+ const step = journey.steps.find(step => step.id === id);
+ if (step) {
+ step[field] = value;
+ saveJourney();
+ }
+ }
+
+ // Clear entire journey
+ function clearJourney() {
+ if (confirm('Are you sure you want to clear the entire journey? This cannot be undone.')) {
+ journey.steps = [];
+ saveJourney();
+ renderJourney();
+ }
+ }
+
+ // Export journey
+ function exportJourney() {
+ const modal = createModal('Export Journey',
+ 'Copy this JSON data to save your journey:',
+ JSON.stringify(journey, null, 2),
+ true
+ );
+ document.body.appendChild(modal);
+ modal.classList.add('active');
+
+ // Select all text in textarea
+ const textarea = modal.querySelector('textarea');
+ textarea.select();
+ }
+
+ // Import journey
+ function importJourney() {
+ const modal = createModal('Import Journey',
+ 'Paste your journey JSON data below:',
+ '',
+ false,
+ function(textarea) {
+ try {
+ const imported = JSON.parse(textarea.value);
+ if (imported.steps && Array.isArray(imported.steps)) {
+ if (confirm('This will replace your current journey. Continue?')) {
+ journey = imported;
+ saveJourney();
+ renderJourney();
+ closeModal(modal);
+ }
+ } else {
+ alert('Invalid journey data. Please check the format.');
+ }
+ } catch (e) {
+ alert('Error parsing JSON data. Please check the format.');
+ }
+ }
+ );
+ document.body.appendChild(modal);
+ modal.classList.add('active');
+ }
+
+ // Create modal
+ function createModal(title, message, content, readonly, onConfirm) {
+ const modal = document.createElement('div');
+ modal.className = 'modal';
+
+ const modalContent = document.createElement('div');
+ modalContent.className = 'modal-content';
+
+ const header = document.createElement('div');
+ header.className = 'modal-header';
+ header.innerHTML = `
+