Web Pages Medium
Podcast Platform
A podcast platform landing page featuring a sticky audio player UI, episode card grid, host bio section, and category filter — styled like Spotify meets editorial.
Open in Lab
MCP
gsap scrolltrigger lenis css vanilla-js
Targets: JS HTML
Code
/* ── Reset & Base ──────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--dark: #050910;
--dark2: #0d1117;
--accent: #1db954;
--text: #f2f6ff;
--muted: #64748b;
--border: rgba(242, 246, 255, 0.08);
--surface: rgba(242, 246, 255, 0.04);
--radius: 12px;
}
html {
scroll-behavior: smooth;
}
body {
background: var(--dark);
color: var(--text);
font-family: system-ui, "Inter", -apple-system, sans-serif;
line-height: 1.6;
overflow-x: hidden;
}
/* ── Nav ───────────────────────────────────────────────────────────────────── */
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 48px;
background: rgba(5, 9, 16, 0.8);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border);
}
.nav-logo {
display: flex;
align-items: center;
gap: 8px;
font-size: 1.1rem;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text);
text-decoration: none;
}
.nav-logo-icon {
color: var(--accent);
}
.nav-links {
display: flex;
align-items: center;
gap: 32px;
list-style: none;
}
.nav-links a {
color: var(--muted);
text-decoration: none;
font-size: 0.875rem;
font-weight: 500;
transition: color 0.2s;
}
.nav-links a:hover {
color: var(--text);
}
.btn-subscribe {
background: var(--accent);
color: #000;
border: none;
padding: 9px 20px;
border-radius: 50px;
font-size: 0.875rem;
font-weight: 600;
cursor: pointer;
transition: opacity 0.2s, transform 0.2s;
}
.btn-subscribe:hover {
opacity: 0.85;
transform: translateY(-1px);
}
/* ── Hero ──────────────────────────────────────────────────────────────────── */
.hero {
min-height: 100vh;
padding: 120px 48px 80px;
background: radial-gradient(
ellipse 80% 60% at 60% 50%,
rgba(29, 185, 84, 0.06) 0%,
transparent 70%
);
}
.hero-eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 32px;
}
.live-dot {
width: 6px;
height: 6px;
background: var(--accent);
border-radius: 50%;
animation: live-pulse 1.2s ease-in-out infinite;
}
@keyframes live-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.35;
transform: scale(0.6);
}
}
.hero-content {
display: flex;
align-items: flex-start;
gap: 64px;
}
.hero-text {
flex: 1;
}
.hero-show-label {
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 12px;
}
.hero-title {
font-size: clamp(2.4rem, 5vw, 4rem);
font-weight: 800;
line-height: 1.05;
letter-spacing: -0.03em;
margin-bottom: 16px;
}
.hero-desc {
font-size: 1.05rem;
color: var(--muted);
max-width: 440px;
margin-bottom: 32px;
line-height: 1.7;
}
/* Episode card in hero */
.hero-episode-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 20px;
max-width: 460px;
}
.episode-card-meta {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.ep-number {
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
}
.ep-tag {
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--accent);
background: rgba(29, 185, 84, 0.12);
border: 1px solid rgba(29, 185, 84, 0.3);
padding: 2px 9px;
border-radius: 50px;
}
.ep-title {
font-size: 1rem;
font-weight: 700;
line-height: 1.35;
margin-bottom: 6px;
}
.ep-guest {
font-size: 0.82rem;
color: var(--muted);
margin-bottom: 16px;
}
.ep-footer {
display: flex;
align-items: center;
gap: 14px;
}
.play-btn {
display: flex;
align-items: center;
gap: 8px;
background: var(--accent);
color: #000;
border: none;
padding: 9px 18px;
border-radius: 50px;
font-size: 0.82rem;
font-weight: 700;
cursor: pointer;
transition: opacity 0.2s, transform 0.2s;
}
.play-btn:hover {
opacity: 0.85;
transform: scale(1.02);
}
.play-btn.playing {
background: rgba(29, 185, 84, 0.2);
color: var(--accent);
border: 1px solid rgba(29, 185, 84, 0.4);
}
.ep-duration {
font-size: 0.8rem;
color: var(--muted);
}
/* Waveform visual */
.hero-waveform {
flex: 0 0 280px;
padding-top: 56px;
display: flex;
flex-direction: column;
gap: 16px;
}
.waveform-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent);
}
.waveform-bars {
display: flex;
align-items: flex-end;
gap: 3px;
height: 72px;
}
.waveform-bars span {
flex: 1;
height: var(--h, 50%);
background: var(--accent);
border-radius: 2px 2px 0 0;
opacity: 0.65;
animation: wave-bar 1.4s ease-in-out infinite;
}
.waveform-bars span:nth-child(2n) {
animation-delay: 0.15s;
}
.waveform-bars span:nth-child(3n) {
animation-delay: 0.3s;
}
.waveform-bars span:nth-child(5n) {
animation-delay: 0.45s;
}
.waveform-bars span:nth-child(7n) {
animation-delay: 0.6s;
}
.waveform-bars span:nth-child(11n) {
animation-delay: 0.75s;
}
@keyframes wave-bar {
0%,
100% {
opacity: 0.3;
transform: scaleY(0.5);
}
50% {
opacity: 1;
transform: scaleY(1);
}
}
.waveform-progress {
display: flex;
flex-direction: column;
gap: 6px;
}
.waveform-track {
height: 3px;
background: var(--border);
border-radius: 2px;
overflow: hidden;
}
.waveform-fill {
height: 100%;
background: var(--accent);
border-radius: 2px;
}
.waveform-times {
display: flex;
justify-content: space-between;
font-size: 0.72rem;
color: var(--muted);
font-variant-numeric: tabular-nums;
}
/* ── Section Shared ────────────────────────────────────────────────────────── */
.episodes-section,
.platforms-section {
padding: 96px 48px;
}
.host-section {
padding: 96px 48px;
background: var(--dark2);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.section-header {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin-bottom: 32px;
}
.section-title {
font-size: clamp(1.6rem, 3vw, 2.2rem);
font-weight: 800;
letter-spacing: -0.025em;
}
.ep-count {
font-size: 0.85rem;
color: var(--muted);
padding-bottom: 4px;
}
/* ── Filter Pills ──────────────────────────────────────────────────────────── */
.filter-pills {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-bottom: 36px;
}
.pill {
padding: 7px 16px;
border-radius: 50px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--muted);
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.pill:hover {
border-color: rgba(29, 185, 84, 0.3);
color: var(--text);
}
.pill.active {
background: rgba(29, 185, 84, 0.12);
border-color: rgba(29, 185, 84, 0.5);
color: var(--accent);
}
/* ── Episodes Grid ─────────────────────────────────────────────────────────── */
.episodes-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
@media (max-width: 1100px) {
.episodes-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.episodes-grid {
grid-template-columns: 1fr;
}
}
.ep-card {
background: var(--dark2);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 18px;
display: flex;
flex-direction: column;
gap: 8px;
cursor: pointer;
transition: transform 0.25s, border-color 0.25s, box-shadow 0.25s;
}
.ep-card:hover {
transform: translateY(-4px);
border-color: rgba(29, 185, 84, 0.25);
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.4);
}
.ep-card-top {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 4px;
}
.ep-card-number {
font-size: 0.7rem;
color: var(--muted);
font-variant-numeric: tabular-nums;
}
.ep-card-tag {
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
padding: 3px 8px;
border-radius: 50px;
}
.ep-card-tag.design {
background: rgba(99, 102, 241, 0.12);
color: #818cf8;
border: 1px solid rgba(99, 102, 241, 0.25);
}
.ep-card-tag.tech {
background: rgba(29, 185, 84, 0.12);
color: var(--accent);
border: 1px solid rgba(29, 185, 84, 0.25);
}
.ep-card-tag.business {
background: rgba(251, 191, 36, 0.12);
color: #fbbf24;
border: 1px solid rgba(251, 191, 36, 0.25);
}
.ep-card-tag.science {
background: rgba(56, 189, 248, 0.12);
color: #38bdf8;
border: 1px solid rgba(56, 189, 248, 0.25);
}
.ep-card-title {
font-size: 0.9rem;
font-weight: 700;
line-height: 1.35;
flex: 1;
}
.ep-card-guest {
font-size: 0.78rem;
color: var(--muted);
}
.ep-card-footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 4px;
}
.ep-card-duration {
font-size: 0.75rem;
color: var(--muted);
}
.ep-play-icon {
background: none;
border: none;
color: var(--muted);
cursor: pointer;
padding: 0;
transition: color 0.2s;
}
.ep-play-icon:hover {
color: var(--accent);
}
.ep-play-icon.playing {
color: var(--accent);
}
.load-more-row {
display: flex;
justify-content: center;
margin-top: 40px;
}
.btn-load-more {
padding: 12px 32px;
border-radius: 50px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--text);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.btn-load-more:hover {
border-color: rgba(29, 185, 84, 0.4);
color: var(--accent);
}
/* ── Host Section ──────────────────────────────────────────────────────────── */
.host-inner {
display: flex;
align-items: flex-start;
gap: 40px;
}
.host-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
background: linear-gradient(135deg, #0f2a14 0%, #0a1a1a 100%);
border: 1px solid rgba(29, 185, 84, 0.2);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
font-weight: 800;
flex-shrink: 0;
color: var(--accent);
}
.host-info {
flex: 1;
}
.host-label {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 8px;
}
.host-name {
font-size: clamp(1.4rem, 2.5vw, 2rem);
font-weight: 800;
letter-spacing: -0.025em;
margin-bottom: 16px;
}
.host-quote {
font-size: 0.95rem;
color: var(--muted);
line-height: 1.75;
border-left: 2px solid var(--accent);
padding-left: 16px;
margin-bottom: 24px;
font-style: italic;
quotes: none;
}
.host-socials {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.social-link {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
border-radius: 50px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--muted);
font-size: 0.8rem;
font-weight: 500;
text-decoration: none;
transition: all 0.2s;
}
.social-link:hover {
border-color: rgba(29, 185, 84, 0.4);
color: var(--accent);
}
/* ── Platforms Section ─────────────────────────────────────────────────────── */
.platforms-section {
text-align: center;
}
.platforms-title {
font-size: 1rem;
color: var(--muted);
margin-bottom: 32px;
font-weight: 500;
}
.platforms-grid {
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
}
.platform-btn {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 24px;
border-radius: 50px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--text);
font-size: 0.875rem;
font-weight: 600;
text-decoration: none;
cursor: pointer;
transition: all 0.25s;
}
.platform-btn:hover {
border-color: rgba(29, 185, 84, 0.35);
background: rgba(29, 185, 84, 0.06);
color: var(--accent);
transform: translateY(-2px);
}
/* ── Footer ────────────────────────────────────────────────────────────────── */
.footer {
padding: 48px;
border-top: 1px solid var(--border);
}
.footer-inner {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 16px;
}
.footer-logo {
font-size: 1rem;
font-weight: 800;
letter-spacing: 0.06em;
}
.footer-copy {
font-size: 0.8rem;
color: var(--muted);
}
.footer-links {
display: flex;
gap: 24px;
}
.footer-links a {
font-size: 0.8rem;
color: var(--muted);
text-decoration: none;
transition: color 0.2s;
}
.footer-links a:hover {
color: var(--text);
}
/* ── Responsive ────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
.nav {
padding: 14px 20px;
}
.nav-links {
display: none;
}
.hero {
padding: 100px 20px 60px;
}
.hero-content {
flex-direction: column;
}
.hero-waveform {
display: none;
}
.episodes-section,
.host-section,
.platforms-section {
padding: 60px 20px;
}
.host-inner {
flex-direction: column;
}
.footer {
padding: 32px 20px;
}
}/* ── lgc-62-podcast-platform · script.js ──────────────────────────────────── */
/* ── Category Filter ───────────────────────────────────────────────────────── */
(function initFilter() {
var pills = document.querySelectorAll(".pill");
var cards = document.querySelectorAll(".ep-card");
if (!pills.length || !cards.length) return;
function applyFilter(category) {
pills.forEach(function (p) {
p.classList.remove("active");
});
cards.forEach(function (card) {
var tag = card.querySelector(".ep-card-tag");
var cardCat = tag ? tag.textContent.trim().toLowerCase() : "";
card.style.display = category === "all" || cardCat === category ? "" : "none";
});
}
pills.forEach(function (pill) {
pill.addEventListener("click", function () {
pill.classList.add("active");
applyFilter(pill.textContent.trim().toLowerCase());
});
});
if (pills[0]) {
pills[0].classList.add("active");
applyFilter("all");
}
})();
/* ── Play / Pause Toggle ───────────────────────────────────────────────────── */
(function initPlayButtons() {
document.querySelectorAll(".play-btn").forEach(function (btn) {
btn.addEventListener("click", function (e) {
e.stopPropagation();
var isPlaying = btn.classList.contains("playing");
document.querySelectorAll(".play-btn.playing").forEach(function (other) {
if (other !== btn) other.classList.remove("playing");
});
btn.classList.toggle("playing", !isPlaying);
});
});
document.querySelectorAll(".ep-play-icon").forEach(function (btn) {
btn.addEventListener("click", function (e) {
e.stopPropagation();
var isPlaying = btn.classList.contains("playing");
document.querySelectorAll(".ep-play-icon.playing").forEach(function (other) {
if (other !== btn) other.classList.remove("playing");
});
btn.classList.toggle("playing", !isPlaying);
});
});
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Frequency — The Podcast for Builders</title>
<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=Playfair+Display:ital,wght@0,700;0,900;1,700&family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
<script type="importmap">{"imports":{"gsap":"https://esm.sh/gsap@3.13.0","gsap/ScrollTrigger":"https://esm.sh/gsap@3.13.0/ScrollTrigger","lenis":"https://esm.sh/lenis@1.1.13/dist/lenis.mjs"}}</script>
</head>
<body>
<!-- NAV -->
<nav class="nav">
<a href="#" class="nav-logo">
<span class="nav-logo-icon">
<svg width="22" height="22" viewBox="0 0 22 22" fill="none">
<rect x="1" y="7" width="2" height="8" rx="1" fill="currentColor"/>
<rect x="5" y="4" width="2" height="14" rx="1" fill="currentColor"/>
<rect x="9" y="2" width="2" height="18" rx="1" fill="currentColor"/>
<rect x="13" y="5" width="2" height="12" rx="1" fill="currentColor"/>
<rect x="17" y="8" width="2" height="6" rx="1" fill="currentColor"/>
</svg>
</span>
FREQUENCY
</a>
<ul class="nav-links">
<li><a href="#">Episodes</a></li>
<li><a href="#">Guests</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Newsletter</a></li>
</ul>
<button class="btn-subscribe">Subscribe Free</button>
</nav>
<!-- HERO -->
<section class="hero">
<div class="hero-eyebrow">
<span class="live-dot"></span>
<span>Latest Episode</span>
</div>
<div class="hero-content">
<div class="hero-text">
<p class="hero-show-label">The Podcast for Builders</p>
<h1 class="hero-title">Frequency</h1>
<p class="hero-desc">Deep conversations with the people shipping products, building companies, and changing the way we work.</p>
<div class="hero-episode-card">
<div class="episode-card-meta">
<span class="ep-number">EP. 142</span>
<span class="ep-tag">Design</span>
</div>
<h2 class="ep-title">The Design Principles Behind Figma's Success</h2>
<p class="ep-guest">with Dylan Field, Co-founder & CEO of Figma</p>
<div class="ep-footer">
<button class="play-btn">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="9" r="8.5" stroke="currentColor"/>
<path d="M7 6l6 3-6 3V6z" fill="currentColor"/>
</svg>
Play Episode
</button>
<span class="ep-duration">1h 24m</span>
</div>
</div>
</div>
<div class="hero-waveform">
<div class="waveform-label">Now Playing</div>
<div class="waveform-bars">
<span style="--h:30%"></span><span style="--h:65%"></span><span style="--h:45%"></span>
<span style="--h:80%"></span><span style="--h:55%"></span><span style="--h:90%"></span>
<span style="--h:40%"></span><span style="--h:70%"></span><span style="--h:35%"></span>
<span style="--h:85%"></span><span style="--h:60%"></span><span style="--h:75%"></span>
<span style="--h:50%"></span><span style="--h:95%"></span><span style="--h:45%"></span>
<span style="--h:68%"></span><span style="--h:30%"></span><span style="--h:78%"></span>
<span style="--h:55%"></span><span style="--h:88%"></span><span style="--h:42%"></span>
<span style="--h:65%"></span><span style="--h:72%"></span><span style="--h:38%"></span>
<span style="--h:82%"></span><span style="--h:58%"></span><span style="--h:92%"></span>
<span style="--h:47%"></span><span style="--h:76%"></span><span style="--h:63%"></span>
<span style="--h:87%"></span><span style="--h:53%"></span><span style="--h:40%"></span>
<span style="--h:70%"></span><span style="--h:85%"></span><span style="--h:33%"></span>
</div>
<div class="waveform-progress">
<div class="waveform-track">
<div class="waveform-fill" style="width: 38%"></div>
</div>
<div class="waveform-times">
<span>32:14</span>
<span>1:24:07</span>
</div>
</div>
</div>
</div>
</section>
<!-- EPISODES -->
<section class="episodes-section">
<div class="section-header">
<h2 class="section-title">All Episodes</h2>
<span class="ep-count">142 episodes</span>
</div>
<!-- FILTER PILLS -->
<div class="filter-pills">
<button class="pill active">All</button>
<button class="pill">Tech</button>
<button class="pill">Design</button>
<button class="pill">Business</button>
<button class="pill">Science</button>
</div>
<!-- EPISODES GRID -->
<div class="episodes-grid">
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">142</span>
<span class="ep-card-tag design">Design</span>
</div>
<h3 class="ep-card-title">The Design Principles Behind Figma's Success</h3>
<p class="ep-card-guest">Dylan Field</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 24m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">141</span>
<span class="ep-card-tag tech">Tech</span>
</div>
<h3 class="ep-card-title">Building at the Speed of Thought: AI-Native Development</h3>
<p class="ep-card-guest">Amjad Masad</p>
<div class="ep-card-footer">
<span class="ep-card-duration">58m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">140</span>
<span class="ep-card-tag business">Business</span>
</div>
<h3 class="ep-card-title">From Zero to $100M ARR Without Enterprise Sales</h3>
<p class="ep-card-guest">Clara Shih</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 08m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">139</span>
<span class="ep-card-tag science">Science</span>
</div>
<h3 class="ep-card-title">What Quantum Computing Means for Software Engineers</h3>
<p class="ep-card-guest">Preskill Lab</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 41m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">138</span>
<span class="ep-card-tag tech">Tech</span>
</div>
<h3 class="ep-card-title">Why Rust Is Eating C++ in Systems Programming</h3>
<p class="ep-card-guest">Jon Gjengset</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 15m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">137</span>
<span class="ep-card-tag design">Design</span>
</div>
<h3 class="ep-card-title">Designing for Accessibility Isn't a Feature, It's a Foundation</h3>
<p class="ep-card-guest">Sarah Fossheim</p>
<div class="ep-card-footer">
<span class="ep-card-duration">52m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">136</span>
<span class="ep-card-tag business">Business</span>
</div>
<h3 class="ep-card-title">The Contrarian Playbook: Growing by Saying No</h3>
<p class="ep-card-guest">Jason Fried</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 02m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
<article class="ep-card">
<div class="ep-card-top">
<span class="ep-card-number">135</span>
<span class="ep-card-tag science">Science</span>
</div>
<h3 class="ep-card-title">Protein Folding, AlphaFold, and the Future of Drug Discovery</h3>
<p class="ep-card-guest">Demis Hassabis</p>
<div class="ep-card-footer">
<span class="ep-card-duration">1h 33m</span>
<button class="ep-play-icon" aria-label="Play">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="15.5" stroke="currentColor"/>
<path d="M13 11l9 5-9 5V11z" fill="currentColor"/>
</svg>
</button>
</div>
</article>
</div>
<div class="load-more-row">
<button class="btn-load-more">Load more episodes</button>
</div>
</section>
<!-- HOST BIO -->
<section class="host-section">
<div class="host-inner">
<div class="host-avatar">MR</div>
<div class="host-info">
<p class="host-label">Your Host</p>
<h2 class="host-name">Marcus Reid</h2>
<blockquote class="host-quote">
"I started Frequency because I was tired of shallow interviews. Every episode, we go long, we go deep, and we don't wrap up until we've actually gotten somewhere interesting."
</blockquote>
<div class="host-socials">
<a href="#" class="social-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.744l7.73-8.835L1.254 2.25H8.08l4.258 5.63 5.906-5.63zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
@marcusreid
</a>
<a href="#" class="social-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z"/><circle cx="4" cy="4" r="2"/></svg>
LinkedIn
</a>
<a href="#" class="social-link">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
Newsletter
</a>
</div>
</div>
</div>
</section>
<!-- SUBSCRIBE PLATFORMS -->
<section class="platforms-section">
<h2 class="platforms-title">Listen wherever you get your podcasts</h2>
<div class="platforms-grid">
<a href="#" class="platform-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/>
</svg>
Spotify
</a>
<a href="#" class="platform-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701"/>
</svg>
Apple Podcasts
</a>
<a href="#" class="platform-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M23.498 6.186a3.016 3.016 0 00-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 00.502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 002.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 002.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>
</svg>
YouTube
</a>
<a href="#" class="platform-btn">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1" fill="currentColor" stroke="none"/>
</svg>
RSS Feed
</a>
</div>
</section>
<!-- FOOTER -->
<footer class="footer">
<div class="footer-inner">
<span class="footer-logo">FREQUENCY</span>
<p class="footer-copy">© 2026 Frequency Podcast. All rights reserved.</p>
<div class="footer-links">
<a href="#">Privacy</a>
<a href="#">Terms</a>
<a href="#">Contact</a>
</div>
</div>
</footer>
<script type="module" src="script.js"></script>
</body>
</html>Podcast Platform
A landing page for a podcast show or network — the editorial aesthetic of a magazine with the dark familiarity of a streaming platform.
Sections
- Hero — Show name, tagline, latest episode featured card, play button
- Player bar — Sticky bottom audio player (progress, play/pause, time, volume mock)
- Episodes — Card grid with episode number, title, duration, category tag
- Categories — Filter pills that animate the grid
- Host — Bio section with photo, quote, social links
- Subscribe — Platform icons (Spotify, Apple Podcasts, etc.) + newsletter
Key UI elements
- Audio player — functional progress scrubbing mock with waveform visualizer
- Episode cards — hover reveals a “play” overlay
- Category filter — JS-driven show/hide with count badge
- Lenis smooth scroll + GSAP stagger on episode grid reveal