Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Sherlock Counter - Ultimate Counting App</title> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
| --success-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
| --dark-bg: #0a0a0a; | |
| --card-bg: rgba(255, 255, 255, 0.05); | |
| --glass-bg: rgba(255, 255, 255, 0.1); | |
| --text-primary: #ffffff; | |
| --text-secondary: #b0b0b0; | |
| --accent: #ff6b6b; | |
| --shadow: 0 25px 45px rgba(0, 0, 0, 0.3); | |
| --glow: 0 0 30px rgba(102, 126, 234, 0.4); | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: var(--dark-bg); | |
| color: var(--text-primary); | |
| overflow-x: hidden; | |
| min-height: 100vh; | |
| position: relative; | |
| } | |
| body::before { | |
| content: ''; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), | |
| radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%), | |
| radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%); | |
| z-index: -1; | |
| animation: float 20s ease-in-out infinite; | |
| } | |
| @keyframes float { | |
| 0%, 100% { transform: scale(1) rotate(0deg); } | |
| 50% { transform: scale(1.05) rotate(180deg); } | |
| } | |
| .header { | |
| text-align: center; | |
| padding: 2rem 1rem; | |
| background: var(--primary-gradient); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .header::after { | |
| content: ''; | |
| position: absolute; | |
| top: -50%; | |
| right: -50%; | |
| width: 200%; | |
| height: 200%; | |
| background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); | |
| animation: rotate 10s linear infinite; | |
| } | |
| @keyframes rotate { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .header h1 { | |
| font-size: clamp(2rem, 5vw, 3.5rem); | |
| font-weight: 800; | |
| margin-bottom: 0.5rem; | |
| text-shadow: 0 4px 10px rgba(0,0,0,0.3); | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .header p { | |
| font-size: 1.1rem; | |
| opacity: 0.9; | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .built-with { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| background: rgba(255,255,255,0.2); | |
| padding: 0.5rem 1rem; | |
| border-radius: 50px; | |
| text-decoration: none; | |
| color: white; | |
| font-weight: 600; | |
| margin-top: 1rem; | |
| transition: all 0.3s ease; | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .built-with:hover { | |
| background: rgba(255,255,255,0.3); | |
| transform: translateY(-2px); | |
| box-shadow: var(--glow); | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 2rem 1rem; | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 3rem; | |
| align-items: start; | |
| } | |
| .counter-card { | |
| background: var(--card-bg); | |
| backdrop-filter: blur(20px); | |
| border-radius: 30px; | |
| padding: 2.5rem; | |
| border: 1px solid var(--glass-bg); | |
| box-shadow: var(--shadow); | |
| transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .counter-card:hover { | |
| transform: translateY(-10px); | |
| box-shadow: 0 35px 60px rgba(0,0,0,0.4); | |
| } | |
| .counter-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: var(--primary-gradient); | |
| opacity: 0.05; | |
| transition: left 0.5s; | |
| } | |
| .counter-card:hover::before { | |
| left: 0; | |
| } | |
| .counter-display { | |
| font-size: clamp(4rem, 15vw, 8rem); | |
| font-weight: 900; | |
| text-align: center; | |
| margin-bottom: 2rem; | |
| background: var(--secondary-gradient); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| text-shadow: 0 0 40px rgba(245, 87, 108, 0.5); | |
| line-height: 1; | |
| animation: countPulse 2s ease-in-out infinite alternate; | |
| } | |
| @keyframes countPulse { | |
| 0% { transform: scale(1); } | |
| 100% { transform: scale(1.02); } | |
| } | |
| .counter-controls { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1.5rem; | |
| align-items: center; | |
| } | |
| .btn { | |
| padding: 1rem 2rem; | |
| border: none; | |
| border-radius: 25px; | |
| font-size: 1.2rem; | |
| font-weight: 700; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| position: relative; | |
| overflow: hidden; | |
| min-width: 200px; | |
| justify-content: center; | |
| } | |
| .btn::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); | |
| transition: left 0.5s; | |
| } | |
| .btn:hover::before { | |
| left: 100%; | |
| } | |
| .btn-primary { | |
| background: var(--primary-gradient); | |
| color: white; | |
| box-shadow: var(--glow); | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-3px) scale(1.05); | |
| box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4); | |
| } | |
| .btn-success { | |
| background: var(--success-gradient); | |
| color: white; | |
| box-shadow: 0 0 25px rgba(79, 172, 254, 0.4); | |
| } | |
| .btn-success:hover { | |
| transform: translateY(-3px) scale(1.05); | |
| box-shadow: 0 15px 35px rgba(79, 172, 254, 0.6); | |
| } | |
| .btn-danger { | |
| background: linear-gradient(135deg, #ff6b6b, #ee5a52); | |
| color: white; | |
| box-shadow: 0 0 25px rgba(255, 107, 107, 0.4); | |
| } | |
| .btn-danger:hover { | |
| transform: translateY(-3px) scale(1.05); | |
| box-shadow: 0 15px 35px rgba(255, 107, 107, 0.6); | |
| } | |
| .btn-reset { | |
| background: linear-gradient(135deg, #6c5ce7, #a29bfe); | |
| color: white; | |
| font-size: 1rem; | |
| padding: 0.75rem 1.5rem; | |
| } | |
| .input-group { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| width: 100%; | |
| max-width: 300px; | |
| } | |
| .input-wrapper { | |
| position: relative; | |
| } | |
| input[type="number"] { | |
| width: 100%; | |
| padding: 1.25rem 1rem 1.25rem 3rem; | |
| background: var(--glass-bg); | |
| border: 2px solid transparent; | |
| border-radius: 20px; | |
| color: var(--text-primary); | |
| font-size: 1.2rem; | |
| font-weight: 600; | |
| backdrop-filter: blur(10px); | |
| transition: all 0.3s ease; | |
| } | |
| input[type="number"]::placeholder { | |
| color: var(--text-secondary); | |
| } | |
| input[type="number"]:focus { | |
| outline: none; | |
| border-color: var(--accent); | |
| box-shadow: 0 0 20px rgba(255, 107, 107, 0.3); | |
| background: rgba(255, 255, 255, 0.15); | |
| } | |
| .input-icon { | |
| position: absolute; | |
| left: 1rem; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| color: var(--text-secondary); | |
| font-size: 1.2rem; | |
| } | |
| .stats-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); | |
| gap: 1.5rem; | |
| margin-top: 2rem; | |
| } | |
| .stat-item { | |
| text-align: center; | |
| padding: 1.5rem; | |
| background: rgba(255, 255, 255, 0.03); | |
| border-radius: 20px; | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .stat-value { | |
| font-size: 2rem; | |
| font-weight: 800; | |
| display: block; | |
| background: var(--success-gradient); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| margin-bottom: 0.25rem; | |
| } | |
| .stat-label { | |
| font-size: 0.9rem; | |
| color: var(--text-secondary); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| } | |
| .history { | |
| grid-column: 1 / -1; | |
| margin-top: 2rem; | |
| } | |
| .history-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| max-height: 300px; | |
| overflow-y: auto; | |
| padding: 1rem; | |
| background: rgba(255, 255, 255, 0.02); | |
| border-radius: 20px; | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .history-item { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1rem; | |
| background: rgba(255, 255, 255, 0.05); | |
| border-radius: 15px; | |
| animation: slideIn 0.3s ease forwards; | |
| opacity: 0; | |
| transform: translateX(-20px); | |
| } | |
| .history-item:nth-child(even) { | |
| animation-direction: reverse; | |
| } | |
| @keyframes slideIn { | |
| to { | |
| opacity: 1; | |
| transform: translateX(0); | |
| } | |
| } | |
| .history-time { | |
| font-size: 0.85rem; | |
| color: var(--text-secondary); | |
| } | |
| @media (max-width: 768px) { | |
| .container { | |
| grid-template-columns: 1fr; | |
| gap: 2rem; | |
| padding: 1rem; | |
| } | |
| .counter-card { | |
| padding: 2rem 1.5rem; | |
| } | |
| .counter-display { | |
| font-size: clamp(3rem, 20vw, 6rem); | |
| } | |
| .btn { | |
| min-width: 180px; | |
| padding: 0.9rem 1.5rem; | |
| font-size: 1rem; | |
| } | |
| } | |
| .sound-toggle { | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| background: var(--glass-bg); | |
| border: 1px solid var(--glass-bg); | |
| border-radius: 50%; | |
| width: 60px; | |
| height: 60px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| backdrop-filter: blur(20px); | |
| transition: all 0.3s ease; | |
| z-index: 1000; | |
| } | |
| .sound-toggle:hover { | |
| background: var(--glass-bg); | |
| box-shadow: var(--glow); | |
| transform: scale(1.1); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="sound-toggle" id="soundToggle"> | |
| <i class="fas fa-volume-up" id="soundIcon"></i> | |
| </div> | |
| <header class="header"> | |
| <h1><i class="fas fa-calculator"></i> Sherlock Counter</h1> | |
| <p>The Ultimate Counting Experience</p> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with"> | |
| <i class="fas fa-rocket"></i> | |
| Built with anycoder | |
| </a> | |
| </header> | |
| <div class="container"> | |
| <div class="counter-card"> | |
| <div class="counter-display" id="counterDisplay">0</div> | |
| <div class="counter-controls"> | |
| <div class="input-group"> | |
| <div class="input-wrapper"> | |
| <i class="fas fa-step-forward input-icon"></i> | |
| <input type="number" id="stepInput" placeholder="Step (1)" min="1" value="1"> | |
| </div> | |
| </div> | |
| <div style="display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center;"> | |
| <button class="btn btn-success" id="incrementBtn"> | |
| <i class="fas fa-plus"></i> Add | |
| </button> | |
| <button class="btn btn-danger" id="decrementBtn"> | |
| <i class="fas fa-minus"></i> Subtract | |
| </button> | |
| </div> | |
| <button class="btn btn-reset" id="resetBtn"> | |
| <i class="fas fa-sync-alt"></i> Reset | |
| </button> | |
| </div> | |
| </div> | |
| <div class="counter-card"> | |
| <h3 style="text-align: center; margin-bottom: 2rem; font-size: 1.5rem;">Statistics</h3> | |
| <div class="stats-grid"> | |
| <div class="stat-item"> | |
| <span class="stat-value" id="totalIncrements">0</span> | |
| <span class="stat-label">Increments</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-value" id="totalDecrements">0</span> | |
| <span class="stat-label">Decrements</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-value" id="totalOperations">0</span> | |
| <span class="stat-label">Operations</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span class="stat-value" id="maxValue">0</span> | |
| <span class="stat-label">Max Value</span> | |
| </div> | |
| </div> | |
| <div class="history"> | |
| <h4 style="margin-bottom: 1rem;">History</h4> | |
| <div class="history-list" id="historyList"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| class SherlockCounter { | |
| constructor() { | |
| this.count = 0; | |
| this.step = 1; | |
| this.history = []; | |
| this.stats = { | |
| increments: 0, | |
| decrements: 0, | |
| operations: 0, | |
| maxValue: 0 | |
| }; | |
| this.soundsEnabled = true; | |
| this.init(); | |
| } | |
| init() { | |
| this.bindEvents(); | |
| this.updateDisplay(); | |
| this.updateStats(); | |
| this.loadState(); | |
| } | |
| bindEvents() { | |
| document.getElementById('incrementBtn').addEventListener('click', () => this.increment()); | |
| document.getElementById('decrementBtn').addEventListener('click', () => this.decrement()); | |
| document.getElementById('resetBtn').addEventListener('click', () => this.reset()); | |
| document.getElementById('stepInput').addEventListener('input', (e) => { | |
| this.step = parseInt(e.target.value) || 1; | |
| }); | |
| document.getElementById('stepInput').addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| this.increment(); | |
| } | |
| }); | |
| document.getElementById('soundToggle').addEventListener('click', () => this.toggleSound()); | |
| // Keyboard shortcuts | |
| document.addEventListener('keydown', (e) => { | |
| if (e.target.tagName === 'INPUT') return; | |
| switch(e.key) { | |
| case '+': | |
| case 'ArrowUp': | |
| e.preventDefault(); | |
| this.increment(); | |
| break; | |
| case '-': | |
| case 'ArrowDown': | |
| e.preventDefault(); | |
| this.decrement(); | |
| break; | |
| case 'r': | |
| case 'R': | |
| case '0': | |
| e.preventDefault(); | |
| this.reset(); | |
| break; | |
| } | |
| }); | |
| } | |
| increment() { | |
| this.count += this.step; | |
| this.stats.increments++; | |
| this.recordHistory('➕ +'.concat(this.step)); | |
| this.updateDisplay(); | |
| this.playSound(800, 0.1); | |
| } | |
| decrement() { | |
| this.count -= this.step; | |
| this.stats.decrements++; | |
| this.recordHistory('➖ -'.concat(this.step)); | |
| this.updateDisplay(); | |
| this.playSound(400, 0.1); | |
| } | |
| reset() { | |
| this.count = 0; | |
| this.recordHistory('🔄 Reset'); | |
| this.updateDisplay(); | |
| this.playSound(600, 0.2); | |
| } | |
| recordHistory(action) { | |
| const timestamp = new Date().toLocaleTimeString(); | |
| this.history.unshift({ action, timestamp, value: this.count }); | |
| if (this.history.length > 10) { | |
| this.history.pop(); | |
| } | |
| this.stats.operations++; | |
| if (this.count > this.stats.maxValue) { | |
| this.stats.maxValue = this.count; | |
| } | |
| this.saveState(); | |
| this.updateHistory(); | |
| this.updateStats(); | |
| } | |
| updateDisplay() { | |
| const display = document.getElementById('counterDisplay'); | |
| display.textContent = this.count.toLocaleString(); | |
| // Animate number change | |
| display.style.transform = 'scale(1.3)'; | |
| setTimeout(() => { | |
| display.style.transform = 'scale(1)'; | |
| }, 150); | |
| } | |
| updateStats() { | |
| document.getElementById('totalIncrements').textContent = this.stats.increments.toLocaleString(); | |
| document.getElementById('totalDecrements').textContent = this.stats.decrements.toLocaleString(); | |
| document.getElementById('totalOperations').textContent = this.stats.operations.toLocaleString(); | |
| document.getElementById('maxValue').textContent = this.stats.maxValue.toLocaleString(); | |
| } | |
| updateHistory() { | |
| const historyList = document.getElementById('historyList'); | |
| historyList.innerHTML = this.history.map((item, index) => ` | |
| <div class="history-item" style="animation-delay: ${index * 0.05}s"> | |
| <span>${item.action} (${item.value})</span> | |
| <span class="history-time">${item.timestamp}</span> | |
| </div> | |
| `).join(''); | |
| } | |
| playSound(frequency, duration) { | |
| if (!this.soundsEnabled) return; | |
| const audioContext = new (window.AudioContext || window.webkitAudioContext)(); | |
| const oscillator = audioContext.createOscillator(); | |
| const gainNode = audioContext.createGain(); | |
| oscillator.connect(gainNode); | |
| gainNode.connect(audioContext.destination); | |
| oscillator.frequency.value = frequency; | |
| oscillator.type = 'sine'; | |
| gainNode.gain.setValueAtTime(0.3, audioContext.currentTime); | |
| gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + duration); | |
| oscillator.start(audioContext.currentTime); | |
| oscillator.stop(audioContext.currentTime + duration); | |
| } | |
| toggleSound() { | |
| this.soundsEnabled = !this.soundsEnabled; | |
| const icon = document.getElementById('soundIcon'); | |
| icon.className = this.soundsEnabled ? 'fas fa-volume-up' : 'fas fa-volume-mute'; | |
| } | |
| saveState() { | |
| const state = { | |
| count: this.count, | |
| step: this.step, | |
| stats: this.stats, | |
| history: this.history | |
| }; | |
| localStorage.setItem('sherlockCounter', JSON.stringify(state)); | |
| } | |
| loadState() { | |
| const saved = localStorage.getItem('sherlockCounter'); | |
| if (saved) { | |
| const state = JSON.parse(saved); | |
| this.count = state.count || 0; | |
| this.step = state.step || 1; | |
| this.stats = state.stats || this.stats; | |
| this.history = state.history || []; | |
| document.getElementById('stepInput').value = this.step; | |
| this.updateDisplay(); | |
| this.updateStats(); | |
| this.updateHistory(); | |
| } | |
| } | |
| } | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new SherlockCounter(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |