diff --git a/iframe.html b/iframe.html index a6801ec..38573af 100644 --- a/iframe.html +++ b/iframe.html @@ -1264,6 +1264,66 @@ text-align: center; } } + + /* Lock Icon Styles */ + .dog-calculator-lock-icon { + display: inline-block; + width: 16px; + height: 16px; + margin-left: 8px; + cursor: pointer; + font-size: 14px; + line-height: 1; + vertical-align: middle; + transition: all 0.2s ease; + user-select: none; + opacity: 0.6; + } + + .dog-calculator-lock-icon:hover { + opacity: 1; + transform: scale(1.1); + } + + .dog-calculator-lock-icon.locked { + color: #f19a5f; + opacity: 1; + font-weight: bold; + } + + .dog-calculator-lock-icon.unlocked { + color: #635870; + } + + .dog-calculator-lock-icon.disabled { + opacity: 0.3; + cursor: not-allowed; + } + + .dog-calculator-lock-icon.disabled:hover { + opacity: 0.3; + transform: none; + } + + /* Dark theme support for lock icons */ + .dog-calculator-container.theme-dark .dog-calculator-lock-icon.unlocked { + color: #b8b0c2; + } + + .dog-calculator-container.theme-dark .dog-calculator-lock-icon.locked { + color: #f19a5f; + } + + /* System theme support for lock icons */ + @media (prefers-color-scheme: dark) { + .dog-calculator-container.theme-system .dog-calculator-lock-icon.unlocked { + color: #b8b0c2; + } + + .dog-calculator-container.theme-system .dog-calculator-lock-icon.locked { + color: #f19a5f; + } + }
@@ -1534,7 +1594,8 @@ name: `Food Source ${this.foodSources.length + 1}`, energy: '', energyUnit: this.isImperial ? 'kcalcup' : 'kcal100g', - percentage: this.foodSources.length === 0 ? 100 : 0 + percentage: this.foodSources.length === 0 ? 100 : 0, + isLocked: false }; this.foodSources.push(foodSource); @@ -1575,12 +1636,24 @@ const count = this.foodSources.length; if (count === 0) return; - const equalPercentage = Math.floor(100 / count); - const remainder = 100 - (equalPercentage * count); + // Only redistribute among unlocked sources + const unlockedSources = this.foodSources.filter(fs => !fs.isLocked); + const lockedSources = this.foodSources.filter(fs => fs.isLocked); + + // Calculate total locked percentage + const totalLockedPercentage = lockedSources.reduce((sum, fs) => sum + fs.percentage, 0); + + // Available percentage for unlocked sources + const availablePercentage = 100 - totalLockedPercentage; + + if (unlockedSources.length > 0) { + const equalPercentage = Math.floor(availablePercentage / unlockedSources.length); + const remainder = availablePercentage - (equalPercentage * unlockedSources.length); - this.foodSources.forEach((fs, index) => { - fs.percentage = equalPercentage + (index < remainder ? 1 : 0); - }); + unlockedSources.forEach((fs, index) => { + fs.percentage = equalPercentage + (index < remainder ? 1 : 0); + }); + } // Update the UI sliders and inputs this.updatePercentageInputs(); @@ -1605,31 +1678,41 @@ this.foodSources[changedIndex].percentage = newPercentage; - // Distribute the difference among other sources proportionally - const otherSources = this.foodSources.filter((fs, index) => index !== changedIndex); - if (otherSources.length === 0) return; - - const totalOtherPercentage = otherSources.reduce((sum, fs) => sum + fs.percentage, 0); + // Only redistribute among unlocked sources (excluding the changed one) + const otherUnlockedSources = this.foodSources.filter((fs, index) => + index !== changedIndex && !fs.isLocked + ); - if (totalOtherPercentage === 0) { - // If all others are 0, distribute equally - const remainingPercentage = 100 - newPercentage; - const equalShare = Math.floor(remainingPercentage / otherSources.length); - const remainder = remainingPercentage - (equalShare * otherSources.length); + if (otherUnlockedSources.length === 0) return; + + // Calculate total locked percentage (excluding the changed source) + const lockedSources = this.foodSources.filter((fs, index) => + index !== changedIndex && fs.isLocked + ); + const totalLockedPercentage = lockedSources.reduce((sum, fs) => sum + fs.percentage, 0); + + // Available percentage for unlocked sources + const availablePercentage = 100 - newPercentage - totalLockedPercentage; + + const totalUnlockedPercentage = otherUnlockedSources.reduce((sum, fs) => sum + fs.percentage, 0); + + if (totalUnlockedPercentage === 0) { + // If all other unlocked sources are 0, distribute equally + const equalShare = Math.floor(availablePercentage / otherUnlockedSources.length); + const remainder = availablePercentage - (equalShare * otherUnlockedSources.length); - otherSources.forEach((fs, index) => { + otherUnlockedSources.forEach((fs, index) => { fs.percentage = equalShare + (index < remainder ? 1 : 0); }); } else { - // Distribute proportionally - const targetTotal = 100 - newPercentage; - const scale = targetTotal / totalOtherPercentage; + // Distribute proportionally among unlocked sources + const scale = availablePercentage / totalUnlockedPercentage; let distributedTotal = 0; - otherSources.forEach((fs, index) => { - if (index === otherSources.length - 1) { + otherUnlockedSources.forEach((fs, index) => { + if (index === otherUnlockedSources.length - 1) { // Last item gets the remainder to ensure exact 100% - fs.percentage = targetTotal - distributedTotal; + fs.percentage = availablePercentage - distributedTotal; } else { fs.percentage = Math.round(fs.percentage * scale); distributedTotal += fs.percentage; @@ -1700,6 +1783,7 @@