Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- index.html +89 -43
index.html
CHANGED
|
@@ -183,9 +183,17 @@
|
|
| 183 |
}
|
| 184 |
|
| 185 |
@keyframes pulse-green {
|
| 186 |
-
0% {
|
| 187 |
-
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
/* Simulator Styles */
|
|
@@ -246,8 +254,15 @@
|
|
| 246 |
}
|
| 247 |
|
| 248 |
@keyframes float {
|
| 249 |
-
|
| 250 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
}
|
| 252 |
|
| 253 |
.pulse-dot {
|
|
@@ -255,8 +270,17 @@
|
|
| 255 |
}
|
| 256 |
|
| 257 |
@keyframes pulse {
|
| 258 |
-
|
| 259 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
}
|
| 261 |
|
| 262 |
.chart-bar {
|
|
@@ -268,14 +292,32 @@
|
|
| 268 |
}
|
| 269 |
|
| 270 |
@keyframes fadeIn {
|
| 271 |
-
from {
|
| 272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 273 |
}
|
| 274 |
|
| 275 |
-
.stagger-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
.stagger-4 { animation-delay: 0.4s; }
|
| 279 |
</style>
|
| 280 |
</head>
|
| 281 |
|
|
@@ -324,7 +366,7 @@
|
|
| 324 |
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 325 |
|
| 326 |
<!-- STANDARD CARD -->
|
| 327 |
-
<div class="price-card bg-white rounded-2xl p-8 cursor-pointer group" onclick="selectPackage('Standard', 2500)">
|
| 328 |
<div class="check-icon">✓</div>
|
| 329 |
<div class="mb-6">
|
| 330 |
<h3 class="text-2xl font-bold text-gray-900">Standard</h3>
|
|
@@ -363,7 +405,7 @@
|
|
| 363 |
<!-- GOLD CARD -->
|
| 364 |
<div
|
| 365 |
class="price-card bg-white rounded-2xl p-8 cursor-pointer relative border-blue-600 ring-1 ring-blue-600 group"
|
| 366 |
-
onclick="selectPackage('Gold', 3500)">
|
| 367 |
<div class="absolute -top-4 left-1/2 -translate-x-1/2">
|
| 368 |
<span class="bg-blue-600 text-white px-5 py-1.5 rounded-full text-sm font-bold tracking-wide shadow-lg shadow-blue-600/30">Consigliato</span>
|
| 369 |
</div>
|
|
@@ -409,7 +451,7 @@
|
|
| 409 |
</div>
|
| 410 |
|
| 411 |
<!-- PLATINUM CARD -->
|
| 412 |
-
<div class="price-card bg-white rounded-2xl p-8 cursor-pointer group" onclick="selectPackage('Platinum', 5000)">
|
| 413 |
<div class="check-icon">✓</div>
|
| 414 |
<div class="mb-6">
|
| 415 |
<h3 class="text-2xl font-bold text-gray-900">Platinum</h3>
|
|
@@ -632,7 +674,9 @@
|
|
| 632 |
<div class="stat-card p-6">
|
| 633 |
<h4 class="text-white font-semibold mb-6 flex items-center gap-2">
|
| 634 |
<svg class="w-5 h-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 635 |
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
|
|
|
|
| 636 |
</svg>
|
| 637 |
Timeline Crescita Mensile
|
| 638 |
</h4>
|
|
@@ -645,7 +689,9 @@
|
|
| 645 |
<div class="stat-card p-6">
|
| 646 |
<h4 class="text-white font-semibold mb-6 flex items-center gap-2">
|
| 647 |
<svg class="w-5 h-5 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 648 |
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
|
|
|
|
| 649 |
</svg>
|
| 650 |
Funnel Conversione
|
| 651 |
</h4>
|
|
@@ -679,7 +725,9 @@
|
|
| 679 |
<div class="mt-8 p-6 bg-white/5 rounded-xl border border-white/10">
|
| 680 |
<h4 class="text-white font-semibold mb-4 flex items-center gap-2">
|
| 681 |
<svg class="w-5 h-5 text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 682 |
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
|
|
|
|
|
| 683 |
</svg>
|
| 684 |
Confronto Investimento vs Ritorno
|
| 685 |
</h4>
|
|
@@ -724,8 +772,10 @@
|
|
| 724 |
</footer>
|
| 725 |
|
| 726 |
<script>
|
|
|
|
| 727 |
let selectedPackageName = null;
|
| 728 |
let packageCost = 0;
|
|
|
|
| 729 |
|
| 730 |
// Format Currency Helper
|
| 731 |
const formatMoney = (amount) => {
|
|
@@ -736,12 +786,13 @@
|
|
| 736 |
return new Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(amount);
|
| 737 |
};
|
| 738 |
|
| 739 |
-
|
|
|
|
| 740 |
// Remove selected class from all cards
|
| 741 |
document.querySelectorAll('.price-card').forEach(card => card.classList.remove('selected'));
|
| 742 |
|
| 743 |
// Add selected class to clicked card
|
| 744 |
-
|
| 745 |
|
| 746 |
// Update State
|
| 747 |
selectedPackageName = name;
|
|
@@ -760,6 +811,7 @@
|
|
| 760 |
calculateROI();
|
| 761 |
}
|
| 762 |
|
|
|
|
| 763 |
function calculateTotal() {
|
| 764 |
// Read inputs
|
| 765 |
const clv = parseFloat(document.getElementById('clvInput').value) || 0;
|
|
@@ -774,25 +826,26 @@
|
|
| 774 |
document.getElementById('costPerClient').textContent = formatMoneyDetailed(costPerClient);
|
| 775 |
|
| 776 |
// Calculate Total Performance Cost
|
| 777 |
-
|
| 778 |
-
document.getElementById('performanceTotal').textContent = formatMoney(
|
| 779 |
|
| 780 |
// Calculate Grand Total
|
| 781 |
-
const total = packageCost +
|
| 782 |
document.getElementById('totalCost').textContent = formatMoney(total);
|
| 783 |
|
| 784 |
// Update ROI calculator
|
| 785 |
calculateROI();
|
| 786 |
}
|
| 787 |
|
|
|
|
| 788 |
function calculateROI() {
|
| 789 |
// Get simulator inputs
|
| 790 |
const months = parseInt(document.getElementById('campaignMonths').value, 10);
|
| 791 |
const conversionRate = parseFloat(document.getElementById('conversionRate').value);
|
| 792 |
-
const avgOrderValue = parseFloat(document.getElementById('avgOrderValue').value) ||
|
| 793 |
|
| 794 |
// Get main calculator values
|
| 795 |
-
const clv = parseFloat(document.getElementById('clvInput').value) ||
|
| 796 |
const performancePercent = parseFloat(document.getElementById('percentageInput').value) || 25;
|
| 797 |
const clientsAcquired = parseInt(document.getElementById('clientsInput').value, 10) || 10;
|
| 798 |
|
|
@@ -800,35 +853,28 @@
|
|
| 800 |
document.getElementById('monthsValue').textContent = months;
|
| 801 |
document.getElementById('conversionValue').textContent = conversionRate;
|
| 802 |
|
| 803 |
-
// Calculate
|
| 804 |
const monthlyRevenue = clientsAcquired * clv;
|
|
|
|
|
|
|
| 805 |
const totalRevenue = monthlyRevenue * months;
|
| 806 |
|
| 807 |
// Calculate investment
|
| 808 |
-
const
|
|
|
|
| 809 |
const totalInvestment = packageCost + performanceCost;
|
| 810 |
|
| 811 |
// Calculate ROI
|
| 812 |
-
|
|
|
|
|
|
|
|
|
|
| 813 |
|
| 814 |
// Calculate break-even (how many clients needed to cover investment)
|
| 815 |
-
const costPerClientAcquired = clv * (performancePercent / 100);
|
| 816 |
const breakEvenClients = costPerClientAcquired > 0 ? Math.ceil(totalInvestment / costPerClientAcquired) : 0;
|
| 817 |
|
| 818 |
// Net per client after costs
|
| 819 |
const netPerClient = clv - costPerClientAcquired;
|
| 820 |
|
| 821 |
// Funnel calculations
|
| 822 |
-
const totalVisits = Math.round(
|
| 823 |
-
const impressions = Math.round(totalVisits * 10);
|
| 824 |
-
const clicks = Math.round(impressions * 0.05); // 5% CTR
|
| 825 |
-
const leads = Math.round(clicks * 0.15); // 15% lead rate
|
| 826 |
-
|
| 827 |
-
// Update UI
|
| 828 |
-
document.getElementById('roiPercent').textContent = `${roi.toFixed(0)}%`;
|
| 829 |
-
document.getElementById('projectedRevenue').textContent = formatMoney(totalRevenue);
|
| 830 |
-
document.getElementById('breakEven').textContent = breakEvenClients;
|
| 831 |
-
document.getElementById('netPerClient').textContent = formatMoney(netPerClient);
|
| 832 |
-
|
| 833 |
-
// Update funnel
|
| 834 |
-
document
|
|
|
|
| 183 |
}
|
| 184 |
|
| 185 |
@keyframes pulse-green {
|
| 186 |
+
0% {
|
| 187 |
+
color: inherit;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
50% {
|
| 191 |
+
color: #16a34a;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
100% {
|
| 195 |
+
color: inherit;
|
| 196 |
+
}
|
| 197 |
}
|
| 198 |
|
| 199 |
/* Simulator Styles */
|
|
|
|
| 254 |
}
|
| 255 |
|
| 256 |
@keyframes float {
|
| 257 |
+
|
| 258 |
+
0%,
|
| 259 |
+
100% {
|
| 260 |
+
transform: translateY(0);
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
50% {
|
| 264 |
+
transform: translateY(-10px);
|
| 265 |
+
}
|
| 266 |
}
|
| 267 |
|
| 268 |
.pulse-dot {
|
|
|
|
| 270 |
}
|
| 271 |
|
| 272 |
@keyframes pulse {
|
| 273 |
+
|
| 274 |
+
0%,
|
| 275 |
+
100% {
|
| 276 |
+
transform: scale(1);
|
| 277 |
+
opacity: 1;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
50% {
|
| 281 |
+
transform: scale(1.5);
|
| 282 |
+
opacity: 0.5;
|
| 283 |
+
}
|
| 284 |
}
|
| 285 |
|
| 286 |
.chart-bar {
|
|
|
|
| 292 |
}
|
| 293 |
|
| 294 |
@keyframes fadeIn {
|
| 295 |
+
from {
|
| 296 |
+
opacity: 0;
|
| 297 |
+
transform: translateY(20px);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
to {
|
| 301 |
+
opacity: 1;
|
| 302 |
+
transform: translateY(0);
|
| 303 |
+
}
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
.stagger-1 {
|
| 307 |
+
animation-delay: 0.1s;
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
.stagger-2 {
|
| 311 |
+
animation-delay: 0.2s;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
.stagger-3 {
|
| 315 |
+
animation-delay: 0.3s;
|
| 316 |
}
|
| 317 |
|
| 318 |
+
.stagger-4 {
|
| 319 |
+
animation-delay: 0.4s;
|
| 320 |
+
}
|
|
|
|
| 321 |
</style>
|
| 322 |
</head>
|
| 323 |
|
|
|
|
| 366 |
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
| 367 |
|
| 368 |
<!-- STANDARD CARD -->
|
| 369 |
+
<div class="price-card bg-white rounded-2xl p-8 cursor-pointer group" onclick="selectPackage('Standard', 2500, this)">
|
| 370 |
<div class="check-icon">✓</div>
|
| 371 |
<div class="mb-6">
|
| 372 |
<h3 class="text-2xl font-bold text-gray-900">Standard</h3>
|
|
|
|
| 405 |
<!-- GOLD CARD -->
|
| 406 |
<div
|
| 407 |
class="price-card bg-white rounded-2xl p-8 cursor-pointer relative border-blue-600 ring-1 ring-blue-600 group"
|
| 408 |
+
onclick="selectPackage('Gold', 3500, this)">
|
| 409 |
<div class="absolute -top-4 left-1/2 -translate-x-1/2">
|
| 410 |
<span class="bg-blue-600 text-white px-5 py-1.5 rounded-full text-sm font-bold tracking-wide shadow-lg shadow-blue-600/30">Consigliato</span>
|
| 411 |
</div>
|
|
|
|
| 451 |
</div>
|
| 452 |
|
| 453 |
<!-- PLATINUM CARD -->
|
| 454 |
+
<div class="price-card bg-white rounded-2xl p-8 cursor-pointer group" onclick="selectPackage('Platinum', 5000, this)">
|
| 455 |
<div class="check-icon">✓</div>
|
| 456 |
<div class="mb-6">
|
| 457 |
<h3 class="text-2xl font-bold text-gray-900">Platinum</h3>
|
|
|
|
| 674 |
<div class="stat-card p-6">
|
| 675 |
<h4 class="text-white font-semibold mb-6 flex items-center gap-2">
|
| 676 |
<svg class="w-5 h-5 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 677 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
| 678 |
+
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z">
|
| 679 |
+
</path>
|
| 680 |
</svg>
|
| 681 |
Timeline Crescita Mensile
|
| 682 |
</h4>
|
|
|
|
| 689 |
<div class="stat-card p-6">
|
| 690 |
<h4 class="text-white font-semibold mb-6 flex items-center gap-2">
|
| 691 |
<svg class="w-5 h-5 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 692 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
| 693 |
+
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z">
|
| 694 |
+
</path>
|
| 695 |
</svg>
|
| 696 |
Funnel Conversione
|
| 697 |
</h4>
|
|
|
|
| 725 |
<div class="mt-8 p-6 bg-white/5 rounded-xl border border-white/10">
|
| 726 |
<h4 class="text-white font-semibold mb-4 flex items-center gap-2">
|
| 727 |
<svg class="w-5 h-5 text-amber-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
| 728 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
| 729 |
+
d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z">
|
| 730 |
+
</path>
|
| 731 |
</svg>
|
| 732 |
Confronto Investimento vs Ritorno
|
| 733 |
</h4>
|
|
|
|
| 772 |
</footer>
|
| 773 |
|
| 774 |
<script>
|
| 775 |
+
// State management
|
| 776 |
let selectedPackageName = null;
|
| 777 |
let packageCost = 0;
|
| 778 |
+
let totalPerformanceCost = 0;
|
| 779 |
|
| 780 |
// Format Currency Helper
|
| 781 |
const formatMoney = (amount) => {
|
|
|
|
| 786 |
return new Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(amount);
|
| 787 |
};
|
| 788 |
|
| 789 |
+
// Package Selection
|
| 790 |
+
function selectPackage(name, cost, element) {
|
| 791 |
// Remove selected class from all cards
|
| 792 |
document.querySelectorAll('.price-card').forEach(card => card.classList.remove('selected'));
|
| 793 |
|
| 794 |
// Add selected class to clicked card
|
| 795 |
+
element.classList.add('selected');
|
| 796 |
|
| 797 |
// Update State
|
| 798 |
selectedPackageName = name;
|
|
|
|
| 811 |
calculateROI();
|
| 812 |
}
|
| 813 |
|
| 814 |
+
// Calculate Total (Section 2)
|
| 815 |
function calculateTotal() {
|
| 816 |
// Read inputs
|
| 817 |
const clv = parseFloat(document.getElementById('clvInput').value) || 0;
|
|
|
|
| 826 |
document.getElementById('costPerClient').textContent = formatMoneyDetailed(costPerClient);
|
| 827 |
|
| 828 |
// Calculate Total Performance Cost
|
| 829 |
+
totalPerformanceCost = clients * costPerClient;
|
| 830 |
+
document.getElementById('performanceTotal').textContent = formatMoney(totalPerformanceCost);
|
| 831 |
|
| 832 |
// Calculate Grand Total
|
| 833 |
+
const total = packageCost + totalPerformanceCost;
|
| 834 |
document.getElementById('totalCost').textContent = formatMoney(total);
|
| 835 |
|
| 836 |
// Update ROI calculator
|
| 837 |
calculateROI();
|
| 838 |
}
|
| 839 |
|
| 840 |
+
// Calculate ROI (Section 3)
|
| 841 |
function calculateROI() {
|
| 842 |
// Get simulator inputs
|
| 843 |
const months = parseInt(document.getElementById('campaignMonths').value, 10);
|
| 844 |
const conversionRate = parseFloat(document.getElementById('conversionRate').value);
|
| 845 |
+
const avgOrderValue = parseFloat(document.getElementById('avgOrderValue').value) || 150;
|
| 846 |
|
| 847 |
// Get main calculator values
|
| 848 |
+
const clv = parseFloat(document.getElementById('clvInput').value) || 300;
|
| 849 |
const performancePercent = parseFloat(document.getElementById('percentageInput').value) || 25;
|
| 850 |
const clientsAcquired = parseInt(document.getElementById('clientsInput').value, 10) || 10;
|
| 851 |
|
|
|
|
| 853 |
document.getElementById('monthsValue').textContent = months;
|
| 854 |
document.getElementById('conversionValue').textContent = conversionRate;
|
| 855 |
|
| 856 |
+
// Calculate monthly revenue (CLV * monthly acquired clients)
|
| 857 |
const monthlyRevenue = clientsAcquired * clv;
|
| 858 |
+
|
| 859 |
+
// Total projected revenue for the campaign period
|
| 860 |
const totalRevenue = monthlyRevenue * months;
|
| 861 |
|
| 862 |
// Calculate investment
|
| 863 |
+
const costPerClientAcquired = clv * (performancePercent / 100);
|
| 864 |
+
const performanceCost = clientsAcquired * costPerClientAcquired;
|
| 865 |
const totalInvestment = packageCost + performanceCost;
|
| 866 |
|
| 867 |
// Calculate ROI
|
| 868 |
+
let roi = 0;
|
| 869 |
+
if (totalInvestment > 0) {
|
| 870 |
+
roi = ((totalRevenue - totalInvestment) / totalInvestment) * 100;
|
| 871 |
+
}
|
| 872 |
|
| 873 |
// Calculate break-even (how many clients needed to cover investment)
|
|
|
|
| 874 |
const breakEvenClients = costPerClientAcquired > 0 ? Math.ceil(totalInvestment / costPerClientAcquired) : 0;
|
| 875 |
|
| 876 |
// Net per client after costs
|
| 877 |
const netPerClient = clv - costPerClientAcquired;
|
| 878 |
|
| 879 |
// Funnel calculations
|
| 880 |
+
const totalVisits = Math.round(clients
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|