← Back to list

Vibe Code Time Counter

Burak Arslan · 2025-07-20 16:33 · 0 claps · 3.7 min read
#vibe-coding #codepen #time
Open on Medium ↗
Wiki topics: 💻 · Programming

Vibe Code Time Counter

<!DOCTYPE html>
<html lang="tr">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Zamanlayıcı Arayüzü</title>
 <link rel="stylesheet" href="style.css">
 <link rel="preconnect" href="https://fonts.googleapis.com">
 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
</head>
<body>
<div class="phone-wrapper">
 <div class="preset-buttons">
 <button class="preset-btn" data-time="5">5 mins</button>
 <button class="preset-btn" data-time="10">10 mins</button>
 <button class="preset-btn active" data-time="20">20 mins</button>
 </div>
<div class="timer-app">
 <div class="time-display">
 <p class="timer-label">Timer</p>
 <h1 id="time-left">20:00</h1>
 <button id="stop-btn">Stop</button>
 </div>
 <div class="progress-container">
 <div class="progress-circle-bg">
 <div id="progress-spinner"></div>
 <div class="progress-inner-circle">
 <button id="pause-play-btn">
 <div class="icon pause-icon">
 <div class="pause-bar"></div>
 <div class="pause-bar"></div>
 </div>
 <div class="icon play-icon" style="display: none;"></div>
 </button>
 </div>
 </div>
 </div>
 </div>
<div class="home-indicator"></div>
 </div>
<script src="script.js"></script>
</body>
</html>
:root {
    --bg-gray: #E1E2E6;
    --app-bg: #1C1C1E;
    --widget-bg: #003865;
    --text-primary: #FFFFFF;
    --text-secondary: #8E8E93;
    --button-inactive: #5A5A5E;
    --button-active: #0A84FF; /* A slightly brighter blue for better visibility */
    --button-stop: #3A3A3C;
    --progress-bar: #50E3C2;
    --progress-track: #2E6C91;
    --font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

body {
    background-color: var(--bg-gray);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    font-family: var(--font-family);
    margin: 0;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.phone-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 20px;
}

.preset-buttons {
    display: flex;
    gap: 12px;
}

.preset-btn {
    border: none;
    padding: 8px 18px;
    border-radius: 16px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-primary);
    background-color: var(--button-inactive);
    cursor: pointer;
    transition: background-color 0.2s ease, transform 0.1s ease;
}

.preset-btn:active {
    transform: scale(0.95);
}

.preset-btn.active {
    background-color: var(--button-active);
}

.timer-app {
    width: 380px;
    height: 180px;
    background-color: var(--app-bg);
    border-radius: 28px;
    padding: 20px 25px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    box-sizing: border-box;
}

.time-display {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    height: 100%;
    color: var(--text-primary);
}

.timer-label {
    font-size: 16px;
    font-weight: 500;
    color: var(--text-secondary);
    margin: 0;
}

#time-left {
    font-size: 60px;
    font-weight: 700;
    margin: 0;
    line-height: 1;
    letter-spacing: 1px;
}

#stop-btn {
    border: none;
    background-color: var(--button-stop);
    color: var(--text-primary);
    font-size: 16px;
    font-weight: 500;
    padding: 10px 24px;
    border-radius: 12px;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

#stop-btn:hover {
    background-color: #4a4a4c;
}

.progress-container {
    width: 140px;
    height: 140px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.progress-circle-bg {
    width: 100%;
    height: 100%;
    background-color: var(--widget-bg);
    border-radius: 24px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}

#progress-spinner {
    position: absolute;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: conic-gradient(var(--progress-bar) 0deg, var(--progress-track) 0deg);
    transition: background 0.2s linear;
}

.progress-inner-circle {
    width: 80px;
    height: 80px;
    background-color: #000000;
    border-radius: 50%;
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: center;
    align-items: center;
}

#pause-play-btn {
    width: 100%;
    height: 100%;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
}

.icon {
    color: white;
}

.pause-icon {
    width: 20px;
    height: 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.pause-bar {
    width: 6px;
    height: 100%;
    background-color: var(--text-primary);
    border-radius: 2px;
}

.play-icon {
    width: 0;
    height: 0;
    border-top: 12px solid transparent;
    border-bottom: 12px solid transparent;
    border-left: 20px solid var(--text-primary);
    margin-left: 5px; /* Visual centering */
}

.home-indicator {
    width: 134px;
    height: 5px;
    background-color: #000000;
    border-radius: 100px;
    opacity: 0.8;
}
document.addEventListener('DOMContentLoaded', () => {
    const timeLeftDisplay = document.getElementById('time-left');
    const stopBtn = document.getElementById('stop-btn');
    const pausePlayBtn = document.getElementById('pause-play-btn');
    const spinner = document.getElementById('progress-spinner');
    const presetBtns = document.querySelectorAll('.preset-btn');
    const pauseIcon = document.querySelector('.pause-icon');
    const playIcon = document.querySelector('.play-icon');

    let countdown;
    let totalTime = 0;
    let remainingTime = 0;
    let isPaused = false;

    function startTimer(minutes) {
        // Clear any existing timer
        clearInterval(countdown);

        // Update active button
        presetBtns.forEach(btn => {
            btn.classList.remove('active');
            if (parseInt(btn.dataset.time) === minutes) {
                btn.classList.add('active');
            }
        });

        totalTime = minutes * 60;
        remainingTime = totalTime;
        isPaused = false;

        updateDisplay(remainingTime);
        updateSpinner(remainingTime);
        showPauseIcon();

        countdown = setInterval(() => {
            if (!isPaused) {
                remainingTime--;
                updateDisplay(remainingTime);
                updateSpinner(remainingTime);
                if (remainingTime <= 0) {
                    clearInterval(countdown);
                }
            }
        }, 1000);
    }

    function updateDisplay(seconds) {
        const mins = Math.floor(seconds / 60);
        const secs = seconds % 60;
        timeLeftDisplay.textContent = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
    }

    function updateSpinner(seconds) {
        if (totalTime === 0) return;
        const percentage = ((totalTime - seconds) / totalTime) * 100;
        const degrees = percentage * 3.6;
        spinner.style.background = `conic-gradient(var(--progress-bar) ${degrees}deg, var(--progress-track) ${degrees}deg)`;
    }

    function stopTimer() {
        clearInterval(countdown);
        remainingTime = totalTime; // Reset to initial time of the active preset
        isPaused = true;
        updateDisplay(remainingTime);
        updateSpinner(remainingTime);
        showPlayIcon();
    }

    function togglePause() {
        if (remainingTime <= 0) return; // Don't do anything if timer is finished

        isPaused = !isPaused;
        if (isPaused) {
            showPlayIcon();
        } else {
            showPauseIcon();
        }
    }

    function showPlayIcon() {
        pauseIcon.style.display = 'none';
        playIcon.style.display = 'block';
    }

    function showPauseIcon() {
        pauseIcon.style.display = 'flex';
        playIcon.style.display = 'none';
    }

    // Event Listeners
    presetBtns.forEach(button => {
        button.addEventListener('click', () => {
            const time = parseInt(button.dataset.time);
            startTimer(time);
        });
    });

    stopBtn.addEventListener('click', stopTimer);
    pausePlayBtn.addEventListener('click', togglePause);

    // Initial state
    startTimer(20); // Start with 20 minutes as in the picture
    togglePause();  // Start in a paused-like state until user interacts
});

[embed]


메타데이터
post_id
679078e791e7
slug
vibe-code-time-counter-679078e791e7
url
https://medium.com/@ebarslann/vibe-code-time-counter-679078e791e7
canonical_url
https://medium.com/@ebarslann/vibe-code-time-counter-679078e791e7
author_url
https://medium.com/@ebarslann
status
ok
fetched_at
2026-06-26 21:52:29