<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster) - ytpipe Lab</title>
<style>
:root {
--white: #FFFFFF;
--gray-50: #FAFAFA;
--gray-100: #F5F5F5;
--gray-200: #E5E5E5;
--gray-300: #D4D4D4;
--gray-600: #525252;
--gray-700: #404040;
--black: #000000;
--blue: #0066FF;
--blue-light: #E6F0FF;
--green: #059669;
--yellow: #F59E0B;
--red: #DC2626;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro', 'Inter', sans-serif;
background: var(--gray-50);
color: var(--black);
line-height: 1.5;
}
.header {
background: var(--white);
border-bottom: 1px solid var(--gray-200);
padding: 12px 24px;
display: flex;
justify-content: space-between;
align-items: center;
position: sticky;
top: 0;
z-index: 100;
}
.logo { font-size: 18px; font-weight: 600; letter-spacing: -0.5px; }
.status-pill {
background: var(--blue-light);
color: var(--blue);
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.container {
max-width: 1440px;
margin: 0 auto;
padding: 24px;
}
.layout {
display: grid;
grid-template-columns: 1fr 360px;
gap: 24px;
}
.score-banner {
background: linear-gradient(135deg, var(--blue), #0052CC);
color: white;
padding: 20px 24px;
border-radius: 12px;
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
}
.score-grade {
font-size: 48px;
font-weight: 700;
min-width: 80px;
text-align: center;
}
.score-number {
font-size: 24px;
font-weight: 700;
}
.score-label {
font-size: 13px;
opacity: 0.9;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.video-container {
background: var(--black);
aspect-ratio: 16/9;
border-radius: 12px;
overflow: hidden;
margin-bottom: 16px;
}
#player {
width: 100%;
height: 100%;
}
.metadata-strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
padding: 16px;
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 12px;
margin-bottom: 16px;
}
.meta-item {
text-align: center;
}
.meta-label {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--gray-600);
font-weight: 600;
}
.meta-value {
font-size: 16px;
font-weight: 700;
margin-top: 4px;
}
.timeline-section {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 12px;
padding: 16px;
margin-bottom: 16px;
}
.timeline-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--gray-600);
margin-bottom: 8px;
font-weight: 600;
}
.timeline-bar {
height: 8px;
background: var(--gray-200);
border-radius: 4px;
position: relative;
cursor: pointer;
}
.timeline-bar:hover {
background: var(--gray-300);
}
.timeline-progress {
height: 100%;
background: var(--blue);
border-radius: 4px;
width: 0%;
transition: width 0.1s linear;
}
.chunk-marker {
position: absolute;
width: 3px;
height: 12px;
background: var(--blue);
top: -2px;
border-radius: 2px;
cursor: pointer;
}
.chunk-marker:hover {
background: var(--yellow);
height: 16px;
top: -4px;
}
.chapters-section {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 12px;
padding: 16px;
margin-bottom: 16px;
}
.chapter-item {
padding: 8px 12px;
border-radius: 6px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
}
.chapter-item:hover {
background: var(--gray-100);
}
.chapter-time {
font-size: 11px;
font-weight: 600;
color: var(--blue);
font-family: 'SF Mono', monospace;
}
.chapter-title {
font-size: 13px;
font-weight: 500;
flex: 1;
margin-left: 12px;
}
.transcript-section {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 12px;
padding: 20px;
max-height: 600px;
overflow-y: auto;
}
.section-header {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--gray-600);
margin-bottom: 16px;
font-weight: 600;
}
.chunk-row {
display: grid;
grid-template-columns: 60px 1fr;
gap: 12px;
padding: 12px;
border-bottom: 1px solid var(--gray-200);
cursor: pointer;
transition: all 0.2s;
}
.chunk-row:hover {
background: var(--gray-50);
}
.chunk-row.active {
background: var(--blue-light);
border-left: 3px solid var(--blue);
}
.chunk-time {
font-size: 11px;
font-weight: 600;
color: var(--blue);
font-family: 'SF Mono', monospace;
}
.chunk-text {
font-size: 13px;
line-height: 1.6;
color: var(--gray-700);
}
/* Sidebar */
.sidebar {
display: flex;
flex-direction: column;
gap: 16px;
}
.card {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 12px;
padding: 16px;
}
.card-title {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--gray-600);
margin-bottom: 12px;
font-weight: 600;
}
.summary-text {
font-size: 14px;
line-height: 1.7;
color: var(--gray-700);
}
.action-item {
display: flex;
align-items: start;
gap: 10px;
padding: 8px 0;
border-bottom: 1px solid var(--gray-100);
}
.action-item:last-child { border-bottom: none; }
.checkbox {
width: 16px;
height: 16px;
border: 2px solid var(--gray-300);
border-radius: 4px;
margin-top: 2px;
cursor: pointer;
}
.checkbox:hover { border-color: var(--blue); }
.action-text {
font-size: 13px;
line-height: 1.5;
color: var(--gray-700);
flex: 1;
}
.concept-pills {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.pill {
background: var(--gray-100);
padding: 4px 10px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
color: var(--gray-700);
}
.gauge-container {
padding: 8px 0;
}
.gauge-label {
font-size: 14px;
font-weight: 600;
margin-bottom: 8px;
}
.gauge-bar {
height: 6px;
background: var(--gray-200);
border-radius: 3px;
overflow: hidden;
}
.gauge-fill {
height: 100%;
background: var(--blue);
border-radius: 3px;
}
.footer {
background: var(--white);
border-top: 1px solid var(--gray-200);
padding: 16px 24px;
margin-top: 40px;
text-align: center;
font-size: 11px;
color: var(--gray-600);
}
</style>
</head>
<body>
<header class="header">
<div class="logo">yt pipe</div>
<div class="status-pill">Processed β</div>
<div style="display: flex; gap: 12px;">
<button style="border: 1px solid var(--gray-200); background: white; padding: 6px 12px; border-radius: 6px; cursor: pointer;">π Export</button>
<button style="border: 1px solid var(--gray-200); background: white; padding: 6px 12px; border-radius: 6px; cursor: pointer;">βοΈ</button>
</div>
</header>
<main class="container">
<div class="layout">
<!-- Main Column -->
<div class="main-col">
<!-- Score Card (Prominent) -->
<div class="score-banner">
<div class="score-grade">C+</div>
<div class="score-details">
<div class="score-number">6.2/10</div>
<div class="score-label">Overall Quality Score</div>
</div>
</div>
<!-- Video Player -->
<div class="video-container">
<div id="player"></div>
</div>
<!-- Metadata Strip -->
<div class="metadata-strip">
<div class="meta-item">
<div class="meta-label">CHANNEL</div>
<div class="meta-value">Rick Astley</div>
</div>
<div class="meta-item">
<div class="meta-label">DURATION</div>
<div class="meta-value">3m 33s</div>
</div>
<div class="meta-item">
<div class="meta-label">VIEWS</div>
<div class="meta-value">1,738,771,804</div>
</div>
<div class="meta-item">
<div class="meta-label">QUALITY</div>
<div class="meta-value">6.2/10</div>
</div>
</div>
<!-- Interactive Timeline -->
<div class="timeline-section">
<div class="timeline-label">TIMELINE</div>
<div class="timeline-bar" id="timeline">
<div class="timeline-progress" id="timeline-progress"></div>
<!-- Chunk markers will be added by JS -->
</div>
</div>
<!-- Chapters Navigation -->
<div class="chapters-section">
<div class="section-header">CHAPTERS (1)</div>
<div class="chapter-item" onclick="seekToTimestamp('0:00')">
<div class="chapter-time">0:00</div>
<div class="chapter-title">Section 1</div>
</div>
</div>
<!-- Transcript Section -->
<div class="transcript-section">
<div class="section-header">TRANSCRIPT (1 CHUNKS)</div>
<div class="chunk-row" data-chunk-id="0" data-timestamp="0:00">
<div class="chunk-time">0:00</div>
<div class="chunk-text">There are no strangers to love You know the rules and something I have They'll commit me to fall out thinking of You won't get this wrong any other guy I just want to tell you how I feel like Gotta ma...</div>
</div>
</div>
</div>
<!-- Sidebar -->
<aside class="sidebar">
<!-- Summary -->
<div class="card">
<div class="card-title">π SUMMARY</div>
<div class="summary-text">Video titled 'Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)' by Rick Astley. Duration: 3m 33s. Contains 1 content segments covering 386 words of transcribed material.</div>
</div>
<!-- Action Items -->
<div class="card">
<div class="card-title">β
ACTION ITEMS</div>
<div class="action-item">
<div class="checkbox"></div>
<div class="action-text">Review video content</div>
</div>
<div class="action-item">
<div class="checkbox"></div>
<div class="action-text">Take notes on key points</div>
</div>
<div class="action-item">
<div class="checkbox"></div>
<div class="action-text">Apply insights to your work</div>
</div>
</div>
<!-- Key Concepts -->
<div class="card">
<div class="card-title">π KEY CONCEPTS</div>
<div class="concept-pills">
<span class="pill">gonna</span>
<span class="pill">never</span>
<span class="pill">give</span>
<span class="pill">tell</span>
<span class="pill">let</span>
<span class="pill">run</span>
<span class="pill">around</span>
<span class="pill">right</span>
<span class="pill">cry</span>
<span class="pill">goodbye</span>
<span class="pill">lie</span>
<span class="pill">hurt</span>
<span class="pill">known</span>
<span class="pill">feel</span>
<span class="pill">understand</span>
</div>
</div>
<!-- Sentiment -->
<div class="card">
<div class="card-title">π SENTIMENT</div>
<div class="gauge-container">
<div class="gauge-label">Neutral</div>
<div class="gauge-bar">
<div class="gauge-fill" style="width: 50%;"></div>
</div>
</div>
</div>
</aside>
</div>
</main>
<footer class="footer">
Processed with whisper-ai-base β’ 2026-02-04 21:33:31 β’ 386 words analyzed β’ ytpipe v2.0
</footer>
<!-- YouTube IFrame API -->
<script src="https://www.youtube.com/iframe_api"></script>
<script>
// Global player variable
let player;
const chunks = [{"id": 0, "text": "There are no strangers to love You know the rules and something I have They'll commit me to fall out thinking of You won't get this wrong any other guy I just want to tell you how I feel like Gotta ma", "timestamp": "0:00", "timestamp_seconds": 0}];
const sections = [{"timestamp": "0:00", "title": "Section 1", "seconds": 0}];
let currentChunkIndex = -1;
// Initialize YouTube player
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
videoId: 'dQw4w9WgXcQ',
width: '100%',
height: '100%',
playerVars: {
'modestbranding': 1,
'rel': 0
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log('β
Player ready');
setupTimeline();
setupChunkMarkers();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
startTimeTracking();
}
}
// Time tracking for active chunk
let timeTracker;
function startTimeTracking() {
if (timeTracker) clearInterval(timeTracker);
timeTracker = setInterval(() => {
if (!player || !player.getCurrentTime) return;
const currentTime = player.getCurrentTime();
updateTimelineProgress(currentTime);
updateActiveChunk(currentTime);
}, 500);
}
function updateTimelineProgress(currentTime) {
const duration = player.getDuration();
const progress = (currentTime / duration) * 100;
document.getElementById('timeline-progress').style.width = progress + '%';
}
function updateActiveChunk(currentTime) {
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
if (currentTime >= chunk.timestamp_seconds) {
if (currentChunkIndex !== i) {
setActiveChunk(i);
}
}
}
}
function setActiveChunk(index) {
// Remove previous active
document.querySelectorAll('.chunk-row').forEach(row => {
row.classList.remove('active');
});
// Set new active
const chunkRow = document.querySelector(`[data-chunk-id="${index}"]`);
if (chunkRow) {
chunkRow.classList.add('active');
chunkRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
currentChunkIndex = index;
}
// Setup timeline click
function setupTimeline() {
const timeline = document.getElementById('timeline');
timeline.addEventListener('click', (e) => {
const rect = timeline.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const percentage = clickX / rect.width;
const duration = player.getDuration();
const seekTime = duration * percentage;
player.seekTo(seekTime, true);
player.playVideo();
});
}
// Setup chunk markers on timeline
function setupChunkMarkers() {
const timeline = document.getElementById('timeline');
const duration = player.getDuration();
chunks.forEach(chunk => {
const marker = document.createElement('div');
marker.className = 'chunk-marker';
marker.style.left = (chunk.timestamp_seconds / duration * 100) + '%';
marker.title = chunk.timestamp;
timeline.appendChild(marker);
});
}
// Seek to timestamp
function seekToTimestamp(timestampStr) {
const seconds = parseTimestamp(timestampStr);
player.seekTo(seconds, true);
player.playVideo();
}
function parseTimestamp(ts) {
const parts = ts.split(':');
if (parts.length === 2) {
return parseInt(parts[0]) * 60 + parseInt(parts[1]);
} else if (parts.length === 3) {
return parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseInt(parts[2]);
}
return 0;
}
// Chunk click handler
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.chunk-row').forEach((row, index) => {
row.addEventListener('click', () => {
const timestamp = row.dataset.timestamp;
seekToTimestamp(timestamp);
});
});
});
</script>
</body>
</html>