anycoder-5115d64b / index.html
637366heh's picture
Upload folder using huggingface_hub
9d312fd verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tally Counter - Advanced Counting App</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--accent-color: #f093fb;
--success-color: #4caf50;
--danger-color: #f5576c;
--warning-color: #fee140;
--bg-primary: #0f0f23;
--bg-secondary: #1a1a2e;
--bg-card: rgba(255, 255, 255, 0.05);
--text-primary: #ffffff;
--text-secondary: #a0a0b8;
--text-muted: #6b7280;
--button-bg: rgba(255, 255, 255, 0.1);
--button-hover: rgba(255, 255, 255, 0.15);
--button-active: rgba(255, 255, 255, 0.2);
--border-color: rgba(255, 255, 255, 0.1);
--shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
--glass-bg: rgba(255, 255, 255, 0.1);
--glass-border: rgba(255, 255, 255, 0.2);
}
body.light-theme {
--bg-primary: #f3f4f6;
--bg-secondary: #ffffff;
--bg-card: rgba(0, 0, 0, 0.03);
--text-primary: #1f2937;
--text-secondary: #4b5563;
--text-muted: #9ca3af;
--button-bg: rgba(0, 0, 0, 0.05);
--button-hover: rgba(0, 0, 0, 0.08);
--button-active: rgba(0, 0, 0, 0.12);
--border-color: rgba(0, 0, 0, 0.1);
--shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
--glass-bg: rgba(255, 255, 255, 0.7);
--glass-border: rgba(0, 0, 0, 0.1);
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
position: relative;
overflow-x: hidden;
}
.animated-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.3;
pointer-events: none;
}
.animated-bg::before,
.animated-bg::after {
content: '';
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
filter: blur(150px);
animation: float 25s infinite ease-in-out;
}
.animated-bg::before {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
top: -250px;
right: -250px;
}
.animated-bg::after {
background: linear-gradient(135deg, var(--accent-color), var(--danger-color));
bottom: -250px;
left: -250px;
animation-delay: 12.5s;
}
@keyframes float {
0%,
100% {
transform: translate(0, 0) scale(1);
}
33% {
transform: translate(100px, -100px) scale(1.1);
}
66% {
transform: translate(-100px, 100px) scale(0.9);
}
}
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
background: var(--glass-bg);
backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border-color);
padding: 20px;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-left {
display: flex;
align-items: center;
gap: 20px;
}
.logo {
font-size: 24px;
font-weight: 700;
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: flex;
align-items: center;
gap: 10px;
}
.header-actions {
display: flex;
gap: 10px;
}
.theme-toggle {
background: var(--button-bg);
border: 1px solid var(--border-color);
border-radius: 12px;
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
color: var(--text-primary);
font-size: 20px;
}
.theme-toggle:hover {
background: var(--button-hover);
transform: rotate(180deg);
}
.main-container {
flex: 1;
padding: 100px 20px 40px;
max-width: 1200px;
width: 100%;
margin: 0 auto;
}
.counters-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.counter-card {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--border-color);
border-radius: 24px;
padding: 30px;
box-shadow: var(--shadow);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.counter-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
transform: scaleX(0);
transition: transform 0.3s ease;
}
.counter-card:hover::before {
transform: scaleX(1);
}
.counter-card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 50px rgba(0, 0, 0, 0.2);
}
.counter-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.counter-name {
font-size: 18px;
font-weight: 600;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 10px;
}
.counter-name-input {
background: transparent;
border: none;
color: var(--text-primary);
font-size: 18px;
font-weight: 600;
outline: none;
padding: 5px;
border-radius: 8px;
transition: background 0.3s ease;
}
.counter-name-input:hover {
background: var(--button-hover);
}
.counter-actions {
display: flex;
gap: 8px;
}
.icon-btn {
background: var(--button-bg);
border: 1px solid var(--border-color);
border-radius: 10px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
color: var(--text-secondary);
}
.icon-btn:hover {
background: var(--button-hover);
color: var(--text-primary);
transform: scale(1.1);
}
.counter-display {
text-align: center;
margin: 30px 0;
position: relative;
}
.counter-value {
font-size: 72px;
font-weight: 700;
color: var(--text-primary);
line-height: 1;
transition: all 0.3s ease;
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.counter-value.pulse {
animation: valuePulse 0.3s ease;
}
@keyframes valuePulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
.counter-controls {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 25px;
}
.control-btn {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border: none;
border-radius: 16px;
padding: 15px 25px;
color: white;
font-size: 18px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
position: relative;
overflow: hidden;
}
.control-btn::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
.control-btn:active::before {
width: 300px;
height: 300px;
}
.control-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
}
.control-btn:active {
transform: translateY(0);
}
.control-btn.decrement {
background: linear-gradient(135deg, var(--danger-color), #ff6b6b);
}
.control-btn.reset {
background: linear-gradient(135deg, var(--warning-color), #fbbf24);
}
.add-counter-btn {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 2px dashed var(--border-color);
border-radius: 24px;
padding: 40px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
cursor: pointer;
transition: all 0.3s ease;
color: var(--text-secondary);
}
.add-counter-btn:hover {
border-color: var(--primary-color);
background: var(--button-hover);
color: var(--primary-color);
transform: translateY(-5px);
}
.add-icon {
font-size: 48px;
}
.stats-container {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--border-color);
border-radius: 24px;
padding: 30px;
margin-bottom: 30px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.stat-item {
text-align: center;
padding: 20px;
background: var(--button-bg);
border-radius: 16px;
transition: all 0.3s ease;
}
.stat-item:hover {
background: var(--button-hover);
transform: translateY(-3px);
}
.stat-value {
font-size: 36px;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 1px;
}
.history-container {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--border-color);
border-radius: 24px;
padding: 30px;
max-height: 400px;
overflow-y: auto;
}
.history-header {
font-size: 20px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.history-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.history-item {
background: var(--button-bg);
border-radius: 12px;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
transition: all 0.3s ease;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.history-item:hover {
background: var(--button-hover);
transform: translateX(5px);
}
.history-time {
font-size: 12px;
color: var(--text-muted);
}
.history-action {
font-size: 14px;
color: var(--text-secondary);
}
.history-value {
font-size: 18px;
font-weight: 600;
color: var(--text-primary);
}
.clear-history-btn {
background: var(--danger-color);
border: none;
border-radius: 10px;
padding: 8px 16px;
color: white;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
}
.clear-history-btn:hover {
transform: scale(1.05);
box-shadow: 0 5px 15px rgba(245, 87, 108, 0.3);
}
@media (max-width: 768px) {
.counters-grid {
grid-template-columns: 1fr;
}
.counter-value {
font-size: 56px;
}
.stats-grid {
grid-template-columns: 1fr;
}
.control-btn {
padding: 12px 20px;
font-size: 16px;
}
}
.toast {
position: fixed;
bottom: 30px;
right: 30px;
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--border-color);
border-radius: 16px;
padding: 16px 24px;
color: var(--text-primary);
font-weight: 500;
box-shadow: var(--shadow);
transform: translateX(400px);
transition: transform 0.3s ease;
z-index: 1000;
}
.toast.show {
transform: translateX(0);
}
</style>
</head>
<body>
<div class="animated-bg"></div>
<header class="header">
<div class="header-left">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank"
style="display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text-secondary); transition: color 0.3s ease;">
<span>โšก</span>
<span style="font-size: 14px;">Built with anycoder</span>
</a>
<div class="logo">
<span>๐Ÿ“Š</span>
<span>Tally Counter</span>
</div>
</div>
<div class="header-actions">
<button class="theme-toggle" onclick="toggleTheme()">
<span id="themeIcon">๐ŸŒ™</span>
</button>
</div>
</header>
<main class="main-container">
<div class="stats-container">
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value" id="totalCounters">1</div>
<div class="stat-label">Total Counters</div>
</div>
<div class="stat-item">
<div class="stat-value" id="totalCount">0</div>
<div class="stat-label">Total Count</div>
</div>
<div class="stat-item">
<div class="stat-value" id="maxCount">0</div>
<div class="stat-label">Highest Count</div>
</div>
<div class="stat-item">
<div class="stat-value" id="avgCount">0</div>
<div class="stat-label">Average Count</div>
</div>
</div>
</div>
<div class="counters-grid" id="countersGrid">
<!-- Counters will be dynamically added here -->
</div>
<div class="add-counter-btn" onclick="addCounter()">
<span class="add-icon">โž•</span>
<span>Add New Counter</span>
</div>
<div class="history-container">
<div class="history-header">
<span>๐Ÿ“œ Activity History</span>
<button class="clear-history-btn" onclick="clearHistory()">Clear History</button>
</div>
<div class="history-list" id="historyList">
<!-- History items will be dynamically added here -->
</div>
</div>
</main>
<div class="toast" id="toast"></div>
<script>
let counters = [
{ id: 1, name: 'Counter 1', value: 0, color: '#667eea' }
];
let history = [];
let counterIdCounter = 2;
const colors = ['#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe', '#00f2fe', '#43e97b', '#38f9d7'];
function initializeApp() {
renderCounters();
updateStats();
loadFromLocalStorage();
}
function renderCounters() {
const grid = document.getElementById('countersGrid');
grid.innerHTML = '';
counters.forEach(counter => {
const card = createCounterCard(counter);
grid.appendChild(card);
});
document.getElementById('totalCounters').textContent = counters.length;
}
function createCounterCard(counter) {
const card = document.createElement('div');
card.className = 'counter-card';
card.innerHTML = `
<div class="counter-header">
<div class="counter-name">
<input type="text" class="counter-name-input" value="${counter.name}"
onchange="updateCounterName(${counter.id}, this.value)"
onfocus="this.select()">
</div>
<div class="counter-actions">
<button class="icon-btn" onclick="duplicateCounter(${counter.id})" title="Duplicate">
๐Ÿ“‹
</button>
<button class="icon-btn" onclick="deleteCounter(${counter.id})" title="Delete">
๐Ÿ—‘๏ธ
</button>
</div>
</div>
<div class="counter-display">
<div class="counter-value" id="value-${counter.id}">${counter.value}</div>
</div>
<div class="counter-controls">
<button class="control-btn decrement" onclick="decrementCounter(${counter.id})">
<span>โž–</span>
<span>-1</span>
</button>
<button class="control-btn reset" onclick="resetCounter(${counter.id})">
<span>๐Ÿ”„</span>
<span>Reset</span>
</button>
<button class="control-btn" onclick="incrementCounter(${counter.id})">
<span>โž•</span>
<span>+1</span>
</button>
</div>
`;
return card;
}
function addCounter() {
const newCounter = {
id: counterIdCounter++,
name: `Counter ${counters.length + 1}`,
value: 0,
color: colors[counters.length % colors.length]
};
counters.push(newCounter);
renderCounters();
updateStats();
saveToLocalStorage();
showToast('New counter added! ๐ŸŽ‰');
addToHistory('Created', newCounter.name, 0);
}
function deleteCounter(id) {
if (counters.length <= 1) {
showToast('Cannot delete the last counter! ๐Ÿšซ');
return;
}
const counter = counters.find(c => c.id === id);
counters = counters.filter(c => c.id !== id);
renderCounters();
updateStats();
saveToLocalStorage();
showToast('Counter deleted! ๐Ÿ—‘๏ธ');
addToHistory('Deleted', counter.name, counter.value);
}
function duplicateCounter(id) {
const original = counters.find(c => c.id === id);
const newCounter = {
id: counterIdCounter++,
name: `${original.name} (Copy)`,
value: original.value,
color: original.color
};
counters.push(newCounter);
renderCounters();
updateStats();
saveToLocalStorage();
showToast('Counter duplicated! ๐Ÿ“‹');
addToHistory('Duplicated', newCounter.name, newCounter.value);
}
function updateCounterName(id, newName) {
const counter = counters.find(c => c.id === id);
const oldName = counter.name;
counter.name = newName || `Counter ${id}`;
saveToLocalStorage();
showToast('Counter renamed! โœ๏ธ');
addToHistory('Renamed', `${oldName} โ†’ ${counter.name}`, counter.value);
}
function incrementCounter(id) {
const counter = counters.find(c => c.id === id);
counter.value++;
updateCounterDisplay(id);
updateStats();
saveToLocalStorage();
addToHistory('Incremented', counter.name, counter.value);
}
function decrementCounter(id) {
const counter = counters.find(c => c.id === id);
if (counter.value > 0) {
counter.value--;
updateCounterDisplay(id);
updateStats();
saveToLocalStorage();
addToHistory('Decremented', counter.name, counter.value);
} else {
showToast('Counter cannot go below 0! โš ๏ธ');
}
}
function resetCounter(id) {
const counter = counters.find(c => c.id === id);
const oldValue = counter.value;
counter.value = 0;
updateCounterDisplay(id);
updateStats();
saveToLocalStorage();
showToast('Counter reset! ๐Ÿ”„');
addToHistory('Reset', counter.name, 0);
}
function updateCounterDisplay(id) {
const display = document.getElementById(`value-${id}`);
const counter = counters.find(c => c.id === id);
display.textContent = counter.value;
display.classList.add('pulse');
setTimeout(() => display.classList.remove('pulse'), 300);
}
function updateStats() {
const totalCount = counters.reduce((sum, c) => sum + c.value, 0);
const maxCount = Math.max(...counters.map(c => c.value));
const avgCount = counters.length > 0 ? Math.round(totalCount / counters.length) : 0;
document.getElementById('totalCount').textContent = totalCount;
document.getElementById('maxCount').textContent = maxCount;
document.getElementById('avgCount').textContent = avgCount;
}
function addToHistory(action, counterName, value) {
const now = new Date();
const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
history.unshift({
action,
counterName,
value,
time: timeString
});
if (history.length > 50) {
history = history.slice(0, 50);
}
renderHistory();
}
function renderHistory() {
const historyList = document.getElementById('historyList');
historyList.innerHTML = '';
if (history.length === 0) {
historyList.innerHTML = '<div style="text-align: center; color: var(--text-muted); padding: 20px;">No activity yet. Start counting! ๐Ÿ“Š</div>';
return;
}
history.forEach(item => {
const historyItem = document.createElement('div');
historyItem.className = 'history-item';
historyItem.innerHTML = `
<div>
<div class="history-action">${item.action}: ${item.counterName}</div>
<div class="history-time">${item.time}</div>
</div>
<div class="history-value">${item.value}</div>
`;
historyList.appendChild(historyItem);
});
}
function clearHistory() {
if (confirm('Are you sure you want to clear all history?')) {
history = [];
renderHistory();
showToast('History cleared! ๐Ÿงน');
}
}
function toggleTheme() {
const body = document.body;
const themeIcon = document.getElementById('themeIcon');
body.classList.toggle('light-theme');
themeIcon.textContent = body.classList.contains('light-theme') ? 'โ˜€๏ธ' : '๐ŸŒ™';
localStorage.setItem('theme', body.classList.contains('light-theme') ? 'light' : 'dark');
}
function showToast(message) {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
function saveToLocalStorage() {
localStorage.setItem('counters', JSON.stringify(counters));
localStorage.setItem('history', JSON.stringify(history));
}
function loadFromLocalStorage() {
const savedCounters = localStorage.getItem('counters');
const savedHistory = localStorage.getItem('history');
const savedTheme = localStorage.getItem('theme');
if (savedCounters) {
counters = JSON.parse(savedCounters);
counterIdCounter = Math.max(...counters.map(c => c.id)) + 1;
}
if (savedHistory) {
history = JSON.parse(savedHistory);
}
if (savedTheme === 'light') {
document.body.classList.add('light-theme');
document.getElementById('themeIcon').textContent = 'โ˜€๏ธ';
}
renderCounters();
renderHistory();
updateStats();
}
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.key >= '1' && e.key <= '9') {
const index = parseInt(e.key) - 1;
if (index < counters.length) {
incrementCounter(counters[index].id);
}
} else if (e.key === 'n' || e.key === 'N') {
addCounter();
} else if (e.key === 't' || e.key === 'T') {
toggleTheme();
} else if (e.key === 'h' || e.key === 'H') {
clearHistory();
}
});
// Initialize the app
initializeApp();
</script>
</body>
</html>