<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Tutoring Earnings Tracker</title>

    <script src="https://cdn.tailwindcss.com"></script>

    <style>

        /* Custom Animations */

        @keyframes slideUpFade {

            from { opacity: 0; transform: translateY(30px); }

            to { opacity: 1; transform: translateY(0); }

        }


        @keyframes pop {

            0% { transform: scale(1); }

            50% { transform: scale(1.15); color: #a5b4fc; } /* text-indigo-300 */

            100% { transform: scale(1); }

        }


        .animate-entry {

            animation: slideUpFade 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;

        }


        .animate-pop {

            animation: pop 0.4s ease-out;

        }


        /* Smooth input transitions */

        .input-field {

            transition: all 0.3s ease;

        }

        .input-field:focus {

            transform: translateY(-2px);

            box-shadow: 0 10px 25px -5px rgba(79, 70, 229, 0.15);

        }

        

        /* Hide number input arrows */

        input::-webkit-outer-spin-button,

        input::-webkit-inner-spin-button {

            -webkit-appearance: none;

            margin: 0;

        }

        input[type=number] {

            -moz-appearance: textfield;

        }

    </style>

</head>

<body class="bg-gradient-to-br from-slate-100 to-indigo-50 min-h-screen p-4 md:p-8 flex items-center justify-center font-sans text-slate-800">


    <!-- Main Card container with entrance animation -->

    <div class="animate-entry max-w-md w-full mx-auto bg-white/90 backdrop-blur-xl rounded-3xl shadow-2xl shadow-indigo-200/50 border border-white p-6 sm:p-8">

        

        <!-- Header -->

        <div class="flex items-center justify-between mb-8">

            <h1 class="text-2xl sm:text-3xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-purple-600 tracking-tight">

                Tutor Tracker

            </h1>

            <div class="bg-indigo-100 text-indigo-600 p-2 sm:p-3 rounded-2xl shadow-sm">

                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">

                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />

                </svg>

            </div>

        </div>

        

        <!-- Settings -->

        <div class="grid grid-cols-2 gap-4 mb-8">

            <div class="group">

                <label class="block text-[10px] sm:text-xs font-bold text-slate-400 uppercase tracking-wider mb-2 group-focus-within:text-indigo-500 transition-colors">Threshold (min)</label>

                <input type="number" id="threshold" value="45" class="input-field w-full p-3 sm:p-4 border border-slate-200 rounded-2xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-slate-50 focus:bg-white text-lg font-bold text-slate-700">

            </div>

            <div class="group">

                <label class="block text-[10px] sm:text-xs font-bold text-slate-400 uppercase tracking-wider mb-2 group-focus-within:text-indigo-500 transition-colors">Rate ($/hr)</label>

                <input type="number" id="rate" value="20" class="input-field w-full p-3 sm:p-4 border border-slate-200 rounded-2xl focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none bg-slate-50 focus:bg-white text-lg font-bold text-slate-700">

            </div>

        </div>


        <!-- Logging Session -->

        <div class="mb-8">

            <label class="block text-[10px] sm:text-xs font-bold text-slate-400 uppercase tracking-wider mb-2 focus-within:text-indigo-500 transition-colors">Log New Session</label>

            <div class="flex gap-2 sm:gap-3 relative">

                <input type="number" id="minutes" placeholder="Minutes..." class="input-field flex-1 p-3 sm:p-4 border border-slate-200 rounded-2xl outline-none bg-slate-50 focus:bg-white focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 text-lg font-medium placeholder-slate-300">

                <button id="addBtn" onclick="addSession()" class="bg-gradient-to-tr from-indigo-600 to-indigo-500 hover:from-indigo-500 hover:to-indigo-400 active:scale-95 text-white font-semibold px-4 sm:px-6 py-3 sm:py-4 rounded-2xl shadow-lg shadow-indigo-200 hover:shadow-indigo-300 transition-all duration-200 flex items-center justify-center min-w-[100px]">

                    <span id="btnText">Add</span>

                </button>

            </div>

        </div>


        <!-- Dashboard Display -->

        <div class="relative overflow-hidden bg-slate-900 rounded-3xl p-6 sm:p-8 text-center shadow-xl">

            <!-- Background decorative blur elements -->

            <div class="absolute -top-12 -right-12 w-40 h-40 bg-indigo-500 rounded-full mix-blend-screen filter blur-3xl opacity-40"></div>

            <div class="absolute -bottom-12 -left-12 w-40 h-40 bg-purple-500 rounded-full mix-blend-screen filter blur-3xl opacity-40"></div>


            <div class="relative z-10">

                <p class="text-xs sm:text-sm text-indigo-300 font-medium tracking-widest uppercase mb-1">Total Earned</p>

                <!-- This element animates when earnings update -->

                <div id="totalEarnings" class="text-5xl sm:text-6xl font-black text-white my-2 tracking-tight inline-block transition-transform duration-300">$0.00</div>

                

                <div class="mt-6 pt-5 border-t border-slate-700/50 flex justify-between items-center text-sm">

                    <span class="text-slate-400 font-medium">Minutes Logged</span>

                    <span id="totalMins" class="font-bold text-indigo-200 bg-white/10 px-3 py-1 rounded-xl shadow-inner">0</span>

                </div>

            </div>

        </div>


        <!-- Reset Data -->

        <button onclick="resetData()" class="mt-8 w-full flex items-center justify-center gap-2 text-slate-400 hover:text-red-500 text-sm font-medium transition-colors p-3 rounded-xl hover:bg-red-50 active:scale-95 group">

            <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 group-hover:animate-pulse" fill="none" viewBox="0 0 24 24" stroke="currentColor">

                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />

            </svg>

            Reset All History

        </button>

    </div>


    <script>

        let data = JSON.parse(localStorage.getItem('tutorData')) || { totalMinutes: 0 };

        let lastEarningsStr = "$0.00";


        function updateUI(triggerAnimation = false) {

            const threshold = parseInt(document.getElementById('threshold').value) || 45;

            const rate = parseFloat(document.getElementById('rate').value) || 0;

            

            const payouts = Math.floor(data.totalMinutes / threshold);

            const totalEarnings = (payouts * (threshold / 60) * rate).toFixed(2);

            const newEarningsStr = `$${totalEarnings}`;

            

            const earningsEl = document.getElementById('totalEarnings');

            

            // Only play pop animation if the earnings amount actually changed

            if (triggerAnimation && newEarningsStr !== lastEarningsStr) {

                // Reset animation by temporarily removing the class

                earningsEl.classList.remove('animate-pop');

                void earningsEl.offsetWidth; // Trigger a DOM reflow

                earningsEl.classList.add('animate-pop');

            }

            

            earningsEl.innerText = newEarningsStr;

            lastEarningsStr = newEarningsStr;


            document.getElementById('totalMins').innerText = data.totalMinutes;

            localStorage.setItem('tutorData', JSON.stringify(data));

        }


        function addSession() {

            const minsInput = document.getElementById('minutes');

            const mins = parseInt(minsInput.value);

            

            if (!isNaN(mins) && mins > 0) {

                data.totalMinutes += mins;

                minsInput.value = '';

                

                // Visual Button Feedback

                const btn = document.getElementById('addBtn');

                const btnText = document.getElementById('btnText');

                

                // Swap classes to show success state

                btn.classList.remove('from-indigo-600', 'to-indigo-500');

                btn.classList.add('from-emerald-500', 'to-teal-500');

                btnText.innerText = 'Added! ✓';

                

                setTimeout(() => {

                    btn.classList.remove('from-emerald-500', 'to-teal-500');

                    btn.classList.add('from-indigo-600', 'to-indigo-500');

                    btnText.innerText = 'Add';

                }, 1200);


                // Update UI and trigger earnings pop

                updateUI(true);

            }

        }


        function resetData() {

            if (confirm('Are you sure you want to clear all logged minutes?')) {

                data.totalMinutes = 0;

                updateUI(false);

            }

        }


        // Listen for user changing settings so it updates immediately

        document.getElementById('threshold').addEventListener('input', () => updateUI(true));

        document.getElementById('rate').addEventListener('input', () => updateUI(true));


        // Allow pressing 'Enter' inside the minutes input to log time

        document.getElementById('minutes').addEventListener('keypress', function (e) {

            if (e.key === 'Enter') addSession();

        });


        // Initialize display on load

        updateUI(false);

    </script>

</body>

</html>