Add household size and city multipliers to calculator

D David Veksler · 10 months ago bd43b98fa42d4062cd5fbce99a0663f5e0d72b52
Parent: 9531b1e63
Expanded cost of living data with detailed multipliers for housing, food, transport, and salary adjustment per city. Added household size adjustment logic and new lifestyle items for singles, couples, and families. Updated HTML and JS to support dynamic calculation based on city and household size selection.

2 files changed +206 −47

Diff

diff --git a/lifestyle-calculator-data.json b/lifestyle-calculator-data.json
index 50ed33e..8a7ed2d 100644
--- a/lifestyle-calculator-data.json
+++ b/lifestyle-calculator-data.json
@@ -211,21 +211,79 @@
     }
   ],
   "costOfLivingFactors": [
-    { "city": "Select City (Average US baseline)", "factor": 1.0, "currencySymbol": "$" },
-    { "city": "New York City, USA", "factor": 1.25, "currencySymbol": "$" },
-    { "city": "San Francisco, USA", "factor": 1.3, "currencySymbol": "$" },
-    { "city": "Los Angeles, USA", "factor": 1.15, "currencySymbol": "$" },
-    { "city": "Chicago, USA", "factor": 1.05, "currencySymbol": "$" },
-    { "city": "London, UK", "factor": 1.2, "currencySymbol": "£" },
-    { "city": "Paris, FR", "factor": 1.15, "currencySymbol": "€" },
-    { "city": "Tokyo, JP", "factor": 1.1, "currencySymbol": "Â¥" },
-    { "city": "Sydney, AU", "factor": 1.1, "currencySymbol": "A$" },
-    { "city": "Toronto, CA", "factor": 1.05, "currencySymbol": "C$" },
-    { "city": "Berlin, DE", "factor": 0.9, "currencySymbol": "€" },
-    { "city": "Mexico City, MX", "factor": 0.7, "currencySymbol": "$" },
-    { "city": "Bangalore, IN", "factor": 0.6, "currencySymbol": "₹" },
-    { "city": "Rural Area (Generic)", "factor": 0.85, "currencySymbol": "$" }
+    { "city": "Select City (Average US baseline)", "factor": 1.0, "currencySymbol": "$", "housingMultiplier": 1.0, "foodMultiplier": 1.0, "transportMultiplier": 1.0, "salaryAdjustment": 1.0 },
+    { "city": "Manhattan, NY", "factor": 1.68, "currencySymbol": "$", "housingMultiplier": 2.1, "foodMultiplier": 1.35, "transportMultiplier": 1.15, "salaryAdjustment": 1.25 },
+    { "city": "San Francisco, CA", "factor": 1.62, "currencySymbol": "$", "housingMultiplier": 2.0, "foodMultiplier": 1.25, "transportMultiplier": 1.2, "salaryAdjustment": 1.4 },
+    { "city": "Honolulu, HI", "factor": 1.52, "currencySymbol": "$", "housingMultiplier": 1.8, "foodMultiplier": 1.6, "transportMultiplier": 1.1, "salaryAdjustment": 1.05 },
+    { "city": "Boston, MA", "factor": 1.35, "currencySymbol": "$", "housingMultiplier": 1.7, "foodMultiplier": 1.15, "transportMultiplier": 1.1, "salaryAdjustment": 1.15 },
+    { "city": "Los Angeles, CA", "factor": 1.32, "currencySymbol": "$", "housingMultiplier": 1.65, "foodMultiplier": 1.1, "transportMultiplier": 1.15, "salaryAdjustment": 1.1 },
+    { "city": "Seattle, WA", "factor": 1.28, "currencySymbol": "$", "housingMultiplier": 1.6, "foodMultiplier": 1.05, "transportMultiplier": 1.05, "salaryAdjustment": 1.2 },
+    { "city": "Washington, DC", "factor": 1.25, "currencySymbol": "$", "housingMultiplier": 1.55, "foodMultiplier": 1.1, "transportMultiplier": 1.05, "salaryAdjustment": 1.18 },
+    { "city": "Miami, FL", "factor": 1.18, "currencySymbol": "$", "housingMultiplier": 1.4, "foodMultiplier": 1.05, "transportMultiplier": 1.1, "salaryAdjustment": 0.95 },
+    { "city": "Chicago, IL", "factor": 1.08, "currencySymbol": "$", "housingMultiplier": 1.2, "foodMultiplier": 1.05, "transportMultiplier": 1.05, "salaryAdjustment": 1.05 },
+    { "city": "Denver, CO", "factor": 1.05, "currencySymbol": "$", "housingMultiplier": 1.15, "foodMultiplier": 1.0, "transportMultiplier": 1.0, "salaryAdjustment": 1.02 },
+    { "city": "Atlanta, GA", "factor": 0.98, "currencySymbol": "$", "housingMultiplier": 1.05, "foodMultiplier": 0.95, "transportMultiplier": 1.0, "salaryAdjustment": 0.98 },
+    { "city": "Phoenix, AZ", "factor": 0.96, "currencySymbol": "$", "housingMultiplier": 1.0, "foodMultiplier": 0.95, "transportMultiplier": 0.95, "salaryAdjustment": 0.95 },
+    { "city": "Dallas, TX", "factor": 0.94, "currencySymbol": "$", "housingMultiplier": 0.95, "foodMultiplier": 0.9, "transportMultiplier": 0.9, "salaryAdjustment": 1.0 },
+    { "city": "Rural Midwest, USA", "factor": 0.78, "currencySymbol": "$", "housingMultiplier": 0.65, "foodMultiplier": 0.85, "transportMultiplier": 0.9, "salaryAdjustment": 0.8 },
+    { "city": "Rural South, USA", "factor": 0.72, "currencySymbol": "$", "housingMultiplier": 0.55, "foodMultiplier": 0.8, "transportMultiplier": 0.85, "salaryAdjustment": 0.75 },
+    { "city": "London, UK", "factor": 1.42, "currencySymbol": "£", "housingMultiplier": 1.8, "foodMultiplier": 1.25, "transportMultiplier": 1.15, "salaryAdjustment": 1.1 },
+    { "city": "Paris, FR", "factor": 1.35, "currencySymbol": "€", "housingMultiplier": 1.7, "foodMultiplier": 1.2, "transportMultiplier": 1.0, "salaryAdjustment": 1.05 },
+    { "city": "Zurich, CH", "factor": 1.85, "currencySymbol": "CHF", "housingMultiplier": 2.2, "foodMultiplier": 1.6, "transportMultiplier": 1.3, "salaryAdjustment": 1.45 },
+    { "city": "Tokyo, JP", "factor": 1.28, "currencySymbol": "Â¥", "housingMultiplier": 1.5, "foodMultiplier": 1.15, "transportMultiplier": 1.1, "salaryAdjustment": 1.0 },
+    { "city": "Singapore, SG", "factor": 1.45, "currencySymbol": "S$", "housingMultiplier": 1.9, "foodMultiplier": 1.2, "transportMultiplier": 1.0, "salaryAdjustment": 1.15 },
+    { "city": "Sydney, AU", "factor": 1.32, "currencySymbol": "A$", "housingMultiplier": 1.6, "foodMultiplier": 1.15, "transportMultiplier": 1.1, "salaryAdjustment": 1.08 },
+    { "city": "Toronto, CA", "factor": 1.22, "currencySymbol": "C$", "housingMultiplier": 1.45, "foodMultiplier": 1.1, "transportMultiplier": 1.05, "salaryAdjustment": 1.05 },
+    { "city": "Vancouver, CA", "factor": 1.35, "currencySymbol": "C$", "housingMultiplier": 1.75, "foodMultiplier": 1.15, "transportMultiplier": 1.1, "salaryAdjustment": 1.08 },
+    { "city": "Berlin, DE", "factor": 0.95, "currencySymbol": "€", "housingMultiplier": 1.0, "foodMultiplier": 0.9, "transportMultiplier": 0.85, "salaryAdjustment": 0.9 },
+    { "city": "Amsterdam, NL", "factor": 1.25, "currencySymbol": "€", "housingMultiplier": 1.55, "foodMultiplier": 1.1, "transportMultiplier": 0.95, "salaryAdjustment": 1.05 },
+    { "city": "Dubai, UAE", "factor": 1.18, "currencySymbol": "AED", "housingMultiplier": 1.4, "foodMultiplier": 1.0, "transportMultiplier": 0.9, "salaryAdjustment": 1.2 },
+    { "city": "Mexico City, MX", "factor": 0.65, "currencySymbol": "$", "housingMultiplier": 0.5, "foodMultiplier": 0.7, "transportMultiplier": 0.8, "salaryAdjustment": 0.4 },
+    { "city": "Bangkok, TH", "factor": 0.58, "currencySymbol": "฿", "housingMultiplier": 0.45, "foodMultiplier": 0.6, "transportMultiplier": 0.7, "salaryAdjustment": 0.35 },
+    { "city": "Bangalore, IN", "factor": 0.48, "currencySymbol": "₹", "housingMultiplier": 0.4, "foodMultiplier": 0.55, "transportMultiplier": 0.6, "salaryAdjustment": 0.3 },
+    { "city": "Mumbai, IN", "factor": 0.55, "currencySymbol": "₹", "housingMultiplier": 0.65, "foodMultiplier": 0.6, "transportMultiplier": 0.5, "salaryAdjustment": 0.35 }
   ],
+  "householdSizeAdjustments": {
+    "single": {
+      "label": "Single Adult",
+      "description": "One person household with individual lifestyle needs",
+      "incomeMultiplier": 1.0,
+      "housingMultiplier": 1.0,
+      "foodMultiplier": 1.0,
+      "transportMultiplier": 1.0,
+      "entertainmentMultiplier": 1.0,
+      "healthWellnessMultiplier": 1.0,
+      "servicesMultiplier": 1.0,
+      "educationMultiplier": 1.0,
+      "travelMultiplier": 1.0
+    },
+    "couple": {
+      "label": "Couple / DINK (Dual Income, No Kids)",
+      "description": "Two adults sharing expenses with potential for economies of scale",
+      "incomeMultiplier": 1.6,
+      "housingMultiplier": 1.3,
+      "foodMultiplier": 1.7,
+      "transportMultiplier": 1.4,
+      "entertainmentMultiplier": 1.6,
+      "healthWellnessMultiplier": 1.8,
+      "servicesMultiplier": 1.4,
+      "educationMultiplier": 1.2,
+      "travelMultiplier": 1.8
+    },
+    "family": {
+      "label": "Family with Kids (2 adults + 2 children avg)",
+      "description": "Family household with children requiring education, childcare, and additional living expenses",
+      "incomeMultiplier": 2.2,
+      "housingMultiplier": 1.8,
+      "foodMultiplier": 2.8,
+      "transportMultiplier": 1.6,
+      "entertainmentMultiplier": 2.4,
+      "healthWellnessMultiplier": 2.6,
+      "servicesMultiplier": 2.8,
+      "educationMultiplier": 4.5,
+      "travelMultiplier": 2.2
+    }
+  },
   "lifestyleData": {
     "dining": [
       {
@@ -269,7 +327,24 @@
             "desc": "Family takeout (medium pizza $12-15, Chinese food $25-35, Chipotle bowls $8-10 each) once or twice a month. Maybe a meal at a very casual sit-down restaurant (local diner $8-12/entree, IHOP, Denny's, Applebee's 2-for-$20 deals) for a special occasion.",
             "itemIcon": "bi-shop",
             "financialNote": "Dining out represents 15-20% of food budget. Carefully budgeted treat, not a regular occurrence. Focus on value deals and coupons.",
-            "badges": ["milestone"]
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["family"] }
+          },
+          {
+            "title": "Quick Takeout Treat (~$25-40/month)",
+            "desc": "Solo takeout: $6-8 pizza slice, $4-7 fast food meals, $8-12 ethnic takeout portions. Occasional treat without the family premium cost.",
+            "itemIcon": "bi-person-fill",
+            "financialNote": "Single portion takeout significantly cheaper than family meals.",
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["single"] }
+          },
+          {
+            "title": "Date Night Treats (~$60-100/month)",
+            "desc": "Occasional dinner for two at casual restaurants (Applebee's, chain restaurants $30-50), splitting appetizers and desserts. Coffee dates, happy hour specials.",
+            "itemIcon": "bi-heart-fill",
+            "financialNote": "Couple dining out costs less than family but more than single portions.",
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["couple"] }
           },
           {
             "title": "Packed Lunches & School Meals",
@@ -295,7 +370,24 @@
             "desc": "Eating out as a family at casual chain restaurants (Applebee's $15-20/entree, Chili's, Olive Garden $12-18, TGI Friday's, Red Robin, Panera Bread $8-12) or popular local spots about once a week. Occasional fast-casual upgrades (Chipotle, Five Guys, Shake Shack).",
             "itemIcon": "bi-cup-hot-fill",
             "financialNote": "Dining out budget $50-75/week for family. Becomes a regular part of the family's social life. Still price-conscious but more flexible.",
-            "badges": ["milestone"]
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["family"] }
+          },
+          {
+            "title": "Regular Solo Dining (~$120-180/month)",
+            "desc": "Eating out 3-4 times per week at casual restaurants, food trucks ($8-15/meal), takeout from preferred spots. Building relationships with local establishments.",
+            "itemIcon": "bi-person-check-fill",
+            "financialNote": "Single person dining freedom without family coordination needs.",
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["single"] }
+          },
+          {
+            "title": "Date Nights & Couple Dining (~$160-240/month)",
+            "desc": "Regular date nights at nice casual restaurants (2-3 times/week), wine with dinner, trying new cuisines together. Split appetizers and share experiences.",
+            "itemIcon": "bi-heart-arrow",
+            "financialNote": "Couple dining allows for more adventurous restaurant choices and shared experiences.",
+            "badges": ["milestone"],
+            "modifiers": { "familySize": ["couple"] }
           },
           {
             "title": "Occasional Coffee Shop Visits (~$40-60/month)",
@@ -964,14 +1056,24 @@
             "desc": "Travel primarily consists of visiting family members in nearby towns or states, often staying with them to save on accommodation. Depends heavily on gas prices or bus fares.",
             "itemIcon": "bi-house-heart-fill",
             "financialNote": "Combining family obligations with very limited travel opportunities. Often relies on others for transport.",
-            "badges": ["budgetSmart", "essential"]
+            "badges": ["budgetSmart", "essential"],
+            "modifiers": { "familySize": ["family"] }
           },
           {
             "title": "Day Trips to Nearby Attractions",
             "desc": "Occasional day trips to a nearby beach, lake, or public park if transport can be arranged cheaply (e.g. carpooling, heavily discounted bus fare). Packing all food and drinks from home.",
             "itemIcon": "bi-pin-map",
             "financialNote": "Very budget-conscious short excursions.",
-            "badges": ["budgetSmart"]
+            "badges": ["budgetSmart"],
+            "modifiers": { "familySize": ["family", "couple"] }
+          },
+          {
+            "title": "Solo Adventures & Backpacking",
+            "desc": "Hitchhiking, couch surfing, hostels ($15-25/night), solo camping with minimal gear. Taking advantage of single traveler flexibility and lower costs.",
+            "itemIcon": "bi-backpack3-fill",
+            "financialNote": "Solo travel allows for ultra-budget accommodations and complete flexibility.",
+            "badges": ["budgetSmart"],
+            "modifiers": { "familySize": ["single"] }
           }
         ]
       },
diff --git a/lifestyle-calculator.html b/lifestyle-calculator.html
index fd9babd..2e79e7f 100644
--- a/lifestyle-calculator.html
+++ b/lifestyle-calculator.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+`<!DOCTYPE html>
 <html lang="en">
 
 <head>
@@ -71,7 +71,7 @@
             --info-color: #0dcaf0;
             --dark-color: #212529; /* Main text color */
             --light-color: #f8f9fa; /* Light element backgrounds */
-            
+
             --body-bg-color: #e9ecef;
             --main-container-bg: rgba(255, 255, 255, 0.98);
             --main-container-shadow: 0 15px 40px rgba(0, 0, 0, 0.12);
@@ -88,7 +88,7 @@
             --category-title-letter-spacing: normal;
             --category-title-text-transform: none;
             --category-title-font-weight: 700;
-            
+
             --category-icon-opacity: 0.8;
             --item-title-font-weight: 600;
             --item-description-color: #495057;
@@ -160,7 +160,7 @@
         .theme-luxury { background: linear-gradient(135deg, #fce4ec 0%, #f8bbd0 100%); }
         .theme-ultra { background: linear-gradient(135deg, #ede7f6 0%, #d1c4e9 100%); }
         .theme-elite { background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%); }
-        
+
         /* HNW and UHNW specific backgrounds */
         .theme-hnw-bg { background: linear-gradient(135deg, #FDF5E6 0%, #DAA520 100%); }
         .theme-uhnw-bg { background: linear-gradient(135deg, #1a1a1a 0%, #003366 70%, #00A9E0 100%); }
@@ -186,7 +186,7 @@
             text-transform: var(--page-title-text-transform);
             transition: color 1.2s ease-in-out, letter-spacing 0.5s ease, text-transform 0.5s ease;
         }
-        
+
         body.uhnw-theme-active .page-title {
             letter-spacing: 1.5px;
             text-transform: uppercase;
@@ -439,7 +439,7 @@
             opacity: 0.9;
             transition: color 1.2s ease-in-out;
         }
-        
+
         /* Specific category border colors - these should remain distinct */
         .dining { border-left-color: #fd7e14 !important; }
         .dining .category-icon, .dining .category-item-icon { color: #fd7e14 !important; }
@@ -883,6 +883,7 @@
         let incomeBrackets = [];
         let lifestyleData = {};
         let costOfLivingFactors = [];
+        let householdSizeAdjustments = {};
         let currentCurrencySymbol = "$";
         let budgetChart;
         let lastSliderValue = -1;
@@ -964,16 +965,16 @@
             if (isNaN(r) || isNaN(g) || isNaN(b)) return defaultStyles.primaryColorRGB; // Fallback for parsing errors
             return `${r}, ${g}, ${b}`;
         }
-        
+
         function updatePrimaryRGBVar(hexColor) {
             const rgbString = getRGBFromHex(hexColor);
             document.documentElement.style.setProperty('--primary-color-rgb', rgbString);
         }
 
-        
+
 
         function updateThemeStyling(bracketIndex) {
-            
+
             const body = document.body;
 
             body.classList.remove('hnw-theme-active', 'uhnw-theme-active');
@@ -989,7 +990,7 @@
                 rootStyle.setProperty('--main-container-bg', 'rgba(20, 20, 20, 0.97)'); // Slightly transparent dark
                 rootStyle.setProperty('--main-container-shadow', '0 15px 50px rgba(0, 169, 224, 0.2)');
                 rootStyle.setProperty('--card-shadow', '0 10px 30px rgba(0, 169, 224, 0.15)');
-                
+
                 rootStyle.setProperty('--page-title-color', 'var(--primary-color)');
                 // Typography changes for UHNW are in CSS via body.uhnw-theme-active .page-title
 
@@ -997,7 +998,7 @@
                 rootStyle.setProperty('--item-title-font-weight', '700');
                 rootStyle.setProperty('--item-description-color', '#D3D3D3'); // LightGray for descriptions
                 rootStyle.setProperty('--category-item-border-color', '#444444');
-                
+
                 rootStyle.setProperty('--slider-thumb-bg', 'var(--primary-color)');
                 rootStyle.setProperty('--slider-thumb-border', '3px solid #555555'); // Darker border for thumb
                 rootStyle.setProperty('--slider-thumb-shadow-opacity', '0.7');
@@ -1037,7 +1038,7 @@
                 rootStyle.setProperty('--item-title-font-weight', '600'); // Default is fine
                 rootStyle.setProperty('--item-description-color', '#554216'); // Darker Brown for descriptions
                 rootStyle.setProperty('--category-item-border-color', '#E0D6B3'); // Pale Gold/Beige
-                
+
                 rootStyle.setProperty('--slider-thumb-bg', 'var(--primary-color)');
                 rootStyle.setProperty('--slider-thumb-border', '4px solid #FFF8DC'); // Cornsilk border
                 rootStyle.setProperty('--slider-thumb-shadow-opacity', '0.6');
@@ -1076,9 +1077,9 @@
                 // Ensure primary color itself and its RGB are reset based on defaultStyles.primaryColor
                 rootStyle.setProperty('--primary-color', defaultStyles.primaryColor);
                 updatePrimaryRGBVar(defaultStyles.primaryColor); // Explicitly reset RGB from default hex
-                
+
                 // Let original dynamic background logic take over
-                updateDynamicBackground(bracketIndex, true); 
+                updateDynamicBackground(bracketIndex, true);
             }
             // Apply body background color explicitly after all var changes
             body.style.backgroundColor = rootStyle.getPropertyValue('--body-bg-color').trim();
@@ -1141,7 +1142,7 @@
 
             const isUHNW = document.body.classList.contains('uhnw-theme-active');
             const isHNW = document.body.classList.contains('hnw-theme-active');
-            
+
             const legendTextColor = getComputedStyle(document.documentElement).getPropertyValue('--chart-legend-text-color').trim() || defaultStyles.chartLegendTextColor;
             const chartBorderColor = isUHNW ? '#121212' : (isHNW ? '#FDF5E6' : '#ffffff');
 
@@ -1165,7 +1166,7 @@
                         label: 'Budget Allocation',
                         data: data,
                         backgroundColor: currentPalette,
-                        borderColor: chartBorderColor, 
+                        borderColor: chartBorderColor,
                         borderWidth: 3,
                         hoverBorderColor: isUHNW ? '#333333' : (isHNW ? '#FAF0E6' : '#f8f9fa'),
                         hoverBorderWidth: 1,
@@ -1237,23 +1238,74 @@
             }
         }
 
+        function getCategoryMultiplier(category, selectedColaOption, householdAdjustment) {
+            const categoryMap = {
+                'dining': 'foodMultiplier',
+                'housing': 'housingMultiplier',
+                'transportation': 'transportMultiplier',
+                'travel': 'foodMultiplier', // travel costs often correlate with food costs
+                'entertainment': 'foodMultiplier', // entertainment often correlates with food costs
+                'health-wellness': 'foodMultiplier',
+                'services': 'foodMultiplier',
+                'education': 'foodMultiplier',
+                'financial-services': 'foodMultiplier'
+            };
+            
+            const colaMultiplierType = categoryMap[category] || 'foodMultiplier';
+            const colaMultiplier = parseFloat(selectedColaOption.dataset[colaMultiplierType] || selectedColaOption.dataset.factor);
+            
+            const householdMultiplierMap = {
+                'dining': 'foodMultiplier',
+                'housing': 'housingMultiplier', 
+                'transportation': 'transportMultiplier',
+                'travel': 'travelMultiplier',
+                'entertainment': 'entertainmentMultiplier',
+                'health-wellness': 'healthWellnessMultiplier',
+                'services': 'servicesMultiplier',
+                'education': 'educationMultiplier',
+                'financial-services': 'servicesMultiplier'
+            };
+            
+            const householdMultiplierType = householdMultiplierMap[category] || 'incomeMultiplier';
+            const householdMultiplier = householdAdjustment[householdMultiplierType] || 1.0;
+            
+            return colaMultiplier * householdMultiplier;
+        }
+
         function updateLifestyle() {
-            if (!incomeBrackets || incomeBrackets.length === 0 || !costOfLivingFactors || costOfLivingFactors.length === 0) return;
+            if (!incomeBrackets || incomeBrackets.length === 0 || !costOfLivingFactors || costOfLivingFactors.length === 0 || !householdSizeAdjustments) return;
 
             const selectedBracketIndex = parseInt(slider.value);
             const baseBracket = incomeBrackets[selectedBracketIndex];
             if (!baseBracket) return;
 
-            updateThemeStyling(selectedBracketIndex); 
+            updateThemeStyling(selectedBracketIndex);
 
-            const selectedColaFactor = parseFloat(colaSelectorEl.options[colaSelectorEl.selectedIndex].dataset.factor);
-            currentCurrencySymbol = colaSelectorEl.options[colaSelectorEl.selectedIndex].dataset.currency;
+            const selectedColaOption = colaSelectorEl.options[colaSelectorEl.selectedIndex];
+            const selectedColaFactor = parseFloat(selectedColaOption.dataset.factor);
+            const salaryAdjustment = parseFloat(selectedColaOption.dataset.salaryAdjustment);
+            currentCurrencySymbol = selectedColaOption.dataset.currency;
             const selectedFamilySize = familySizeSelectorEl.value;
 
-            const effectiveIncome = baseBracket.income / selectedColaFactor;
+            // Calculate effective income with household size and salary adjustments
+            const householdAdjustment = householdSizeAdjustments[selectedFamilySize] || { incomeMultiplier: 1.0 };
+            const adjustedIncome = baseBracket.income * salaryAdjustment * householdAdjustment.incomeMultiplier;
+            const effectiveIncome = adjustedIncome / selectedColaFactor;
 
             incomeDisplayEl.textContent = formatIncome(baseBracket.income, currentCurrencySymbol);
-            effectiveIncomeDisplayEl.textContent = selectedColaFactor !== 1.0 ? `(Effectively ~${formatIncome(effectiveIncome, currentCurrencySymbol)} in selected city)` : "";
+
+            let effectiveText = "";
+            if (householdAdjustment.incomeMultiplier !== 1.0) {
+                effectiveText += `(${householdAdjustment.label}: ~${formatIncome(adjustedIncome, currentCurrencySymbol)}`;;
+                if (selectedColaFactor !== 1.0) {
+                    effectiveText += ` → ~${formatIncome(effectiveIncome, currentCurrencySymbol)} in selected city)`;
+                } else {
+                    effectiveText += `)`;
+                }
+            } else if (selectedColaFactor !== 1.0) {
+                effectiveText = `(Effectively ~${formatIncome(effectiveIncome, currentCurrencySymbol)} in selected city)`;
+            }
+            effectiveIncomeDisplayEl.textContent = effectiveText;
             incomeBracketLabelEl.textContent = baseBracket.label;
             incomeBracketDescEl.textContent = baseBracket.description;
 
@@ -1277,7 +1329,7 @@
                     return;
                 }
 
-                const oldHTML = contentDiv.innerHTML; 
+                const oldHTML = contentDiv.innerHTML;
 
                 let itemsToDisplay = [];
                 for (let i = categoryData.length - 1; i >= 0; i--) {
@@ -1311,8 +1363,8 @@
                 if (contentDiv.innerHTML !== oldHTML) {
                     const categoryCard = contentDiv.closest('.lifestyle-category');
                     if (categoryCard) {
-                        categoryCard.classList.remove('highlight-update'); 
-                        void categoryCard.offsetWidth; 
+                        categoryCard.classList.remove('highlight-update');
+                        void categoryCard.offsetWidth;
                         categoryCard.classList.add('highlight-update');
                     }
                 }
@@ -1327,13 +1379,13 @@
             defaultStyles.primaryColorRGB = getRGBFromHex(actualInitialPrimaryColor);
             defaultStyles.pageTitleColor = actualInitialPrimaryColor; // Tie to actual initial
             defaultStyles.sliderThumbBg = actualInitialPrimaryColor;  // Tie to actual initial
-            
+
             // Set all default styles to root, ensuring --primary-color-rgb is derived correctly
             Object.keys(defaultStyles).forEach(key => {
                  const cssVarName = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
                  if (key === 'primaryColorRGB') {
                     // This is handled by updatePrimaryRGBVar called below
-                 } else if (key === 'pageTitleColor' || key === 'sliderThumbBg') { 
+                 } else if (key === 'pageTitleColor' || key === 'sliderThumbBg') {
                     rootStyle.setProperty(cssVarName, `var(--primary-color)`);
                  } else if (key === 'calculatorNoteText') {
                      rootStyle.setProperty(cssVarName, `var(--dark-color)`);
@@ -1354,11 +1406,15 @@
                 option.textContent = factor.city;
                 option.dataset.factor = factor.factor;
                 option.dataset.currency = factor.currencySymbol;
+                option.dataset.housingMultiplier = factor.housingMultiplier || factor.factor;
+                option.dataset.foodMultiplier = factor.foodMultiplier || factor.factor;
+                option.dataset.transportMultiplier = factor.transportMultiplier || factor.factor;
+                option.dataset.salaryAdjustment = factor.salaryAdjustment || 1.0;
                 colaSelectorEl.appendChild(option);
             });
-            
+
             lastSliderValue = parseInt(slider.value);
-            updateLifestyle(); 
+            updateLifestyle();
 
             slider.addEventListener('input', updateLifestyle);
             colaSelectorEl.addEventListener('change', updateLifestyle);
@@ -1382,6 +1438,7 @@
                     incomeBrackets = data.incomeBrackets;
                     lifestyleData = data.lifestyleData;
                     costOfLivingFactors = data.costOfLivingFactors;
+                    householdSizeAdjustments = data.householdSizeAdjustments || {};
                     slider.max = incomeBrackets.length - 1;
                     initializeApp();
                 })