1 2 3<!DOCTYPE html> 4<html lang="en" class="h-full"> 5<head> 6 <meta charset="UTF-8"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <title>About - Code Story | Startup Podcast for Technical Founders</title> 9 10 11 12 <link rel="icon" href="https://podview-media.nyc3.cdn.digitaloceanspaces.com/podcasts/favicons/codestory-favicon.png" type="image/png"> 13 14 15 <!-- Google Fonts for theme typography --> 16 17 <link rel="preconnect" href="https://fonts.googleapis.com"> 18 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 19 <link href="https://fonts.googleapis.com/css2?family=Figtree:wght@400;600;700&family=Figtree:wght@400;500;600&display=swap" rel="stylesheet"> 20 21 22 <!-- Tailwind CSS (built from tailwind.config.js) --> 23 <link rel="stylesheet" href="/static/css/tailwind.7e32b469e897.css"> 24 25 <!-- Plyr (HLS video player chrome) â pinned-major CDN, matches hls.js/htmx/wavesurfer pattern. Plyr JS itself is lazy-loaded by hls-player.js only when a video exists. --> 26 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/plyr@3/dist/plyr.css"> 27 28 <!-- HTMX 2.x --> 29
29<script src="https://unpkg.com/[email protected]"></script>
29 30
30<script> 31 // Configure HTMX to include CSRF token in requests 32 document.addEventListener('htmx:configRequest', function(evt) { 33 const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]')?.value 34 || document.cookie.split('; ').find(row => row.startsWith('csrftoken='))?.split('=')[1]; 35 if (csrfToken) { 36 evt.detail.headers['X-CSRFToken'] = csrfToken; 37 } 38 }); 39 </script>
39 40 41 42
42<script src="https://unpkg.com/[email protected]/dist/wavesurfer.min.js"></script>
42 43 44 <!-- Theme CSS variables and custom styles --> 45 <style> 46 :root { 47 --color-primary: #05bac7; 48 --color-secondary: #4E6E9E; 49 --color-background: #0B1220; 50 --color-text: #EDF2FA; 51 --color-accent: #94c3f4; 52 --font-heading: 'Figtree', serif; 53 --font-body: 'Figtree', sans-serif; 54 --pv-radius-card: 0.5rem; 55 --pv-radius-control: 0.375rem; 56 --pv-shadow-soft: 0 34px 100px -54px rgba(0, 0, 0, 0.92); 57 --pv-surface-alpha: 0.7; 58 --pv-motion-duration: 240ms; 59 60 } 61 .bg-theme-surface { 62 border-radius: var(--pv-radius-card); 63 box-shadow: var(--pv-shadow-soft); 64 } 65 a, button { 66 transition-duration: var(--pv-motion-duration); 67 } 68 69 [x-cloak] { display: none !important; } 70 body { 71 background-color: var(--color-background); 72 color: var(--color-text); 73 font-family: var(--font-body); 74 /* Break long unbreakable tokens (e.g. pasted URL runs in an episode 75 description) so they wrap instead of overflowing horizontally. 76 `anywhere` (not `break-word`) is required: it also shrinks the 77 token's min-content width, so a flex/grid column stops growing to 78 fit it. Inherited, so it applies to all theme text. */ 79 overflow-wrap: anywhere; 80 } 81 /* A failed image can paint its alt text outside the replaced element. 82 Keep the accessible alternative while containing its visual fallback. */ 83 img { overflow: hidden; } 84 h1, h2, h3, h4, h5, h6 { 85 font-family: var(--font-heading); 86 /* Headings opt DOWN from the body's `anywhere` to `break-word`. Both 87 still break a word that cannot fit, but `anywhere` also shrinks 88 min-content width, so a display heading in a flex/grid column got a 89 narrow column and then shattered mid-word: "TECH FOUNDER / S / 90 UNPLUGG / ED" on the arena hero. `break-word` leaves min-content 91 alone, so the column sizes to the longest word and only breaks as a 92 last resort. Body text keeps `anywhere` for pasted URL runs. */ 93 overflow-wrap: break-word; 94 } 95 96 /* Chaptered player - current chapter highlight */ 97 .chaptered-player [data-role="chapter-item"].is-current { 98 background: color-mix(in srgb, var(--color-primary) 12%, transparent); 99 } 100 .chaptered-player [data-role="chapter-item"].is-current > span:last-child { 101 color: var(--color-primary); 102 font-weight: 600; 103 } 104 105 /* Episode detail tabs (dramatic layout). Explicit .is-selected swap avoids 106 aria-selected: variant specificity ties with the base text color. */ 107 .episode-tab { 108 color: var(--color-text); 109 opacity: 0.55; 110 border-color: transparent; 111 } 112 .episode-tab:hover { 113 opacity: 0.85; 114 } 115 .episode-tab.is-selected { 116 color: var(--color-accent); 117 opacity: 1; 118 border-color: var(--color-accent); 119 } 120 121 /* Align Tailwind Typography (prose) with theme tokens. 122 RSS descriptions often come as loose text (no <p> wrappers), so the 123 prose container's own color must be the theme text color â otherwise 124 it falls back to the plugin's slate defaults and looks washed out. */ 125 .prose, 126 .prose.prose-invert { 127 --tw-prose-body: var(--color-text); 128 --tw-prose-headings: var(--color-text); 129 --tw-prose-lead: var(--color-text); 130 --tw-prose-links: var(--color-primary); 131 --tw-prose-bold: var(--color-text); 132 --tw-prose-counters: color-mix(in srgb, var(--color-text) 70%, var(--color-background)); 133 --tw-prose-bullets: color-mix(in srgb, var(--color-text) 50%, var(--color-background)); 134 --tw-prose-hr: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 135 --tw-prose-quotes: var(--color-text); 136 --tw-prose-quote-borders: var(--color-primary); 137 --tw-prose-captions: color-mix(in srgb, var(--color-text) 70%, var(--color-background)); 138 --tw-prose-code: var(--color-text); 139 --tw-prose-pre-code: var(--color-text); 140 --tw-prose-pre-bg: color-mix(in srgb, var(--color-background) 95%, var(--color-text)); 141 --tw-prose-th-borders: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 142 --tw-prose-td-borders: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 143 --tw-prose-invert-body: var(--color-text); 144 --tw-prose-invert-headings: var(--color-text); 145 --tw-prose-invert-lead: var(--color-text); 146 --tw-prose-invert-links: var(--color-primary); 147 --tw-prose-invert-bold: var(--color-text); 148 --tw-prose-invert-counters: color-mix(in srgb, var(--color-text) 70%, var(--color-background)); 149 --tw-prose-invert-bullets: color-mix(in srgb, var(--color-text) 50%, var(--color-background)); 150 --tw-prose-invert-hr: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 151 --tw-prose-invert-quotes: var(--color-text); 152 --tw-prose-invert-quote-borders: var(--color-primary); 153 --tw-prose-invert-captions: color-mix(in srgb, var(--color-text) 70%, var(--color-background)); 154 --tw-prose-invert-code: var(--color-text); 155 --tw-prose-invert-pre-code: var(--color-text); 156 --tw-prose-invert-pre-bg: color-mix(in srgb, var(--color-background) 95%, var(--color-text)); 157 --tw-prose-invert-th-borders: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 158 --tw-prose-invert-td-borders: color-mix(in srgb, var(--color-background) 85%, var(--color-text)); 159 font-family: var(--font-body); 160 } 161 .prose :where(h1, h2, h3, h4, h5, h6):not(:where([class~="not-prose"] *)) { 162 font-family: var(--font-heading); 163 } 164 165 166 167 </style> 168 169 170 171 172 173 174 175<link rel="canonical" href="https://www.codestory.co/about/"> 176 177 178 179<link rel="alternate" type="application/rss+xml" title="Code Story | Startup Podcast for Technical Founders" href="https://feeds.redcircle.com/ac5e79a4-0405-49a3-af2c-02c37f0b3879"> 180 181 182 183
184<meta name="description" content="Learn more about Code Story | Startup Podcast for Technical Founders. Code Story is a startup podcast for technical founders building and scaling software products...."> 185 186 187 188 189<meta property="og:type" content="website"> 190<meta property="og:site_name" content="Code Story | Startup Podcast for Technical Founders"> 191<meta property="og:title" content="About | Code Story | Startup Podcast for Technical Founders"> 192 193<meta property="og:description" content="Learn more about Code Story | Startup Podcast for Technical Founders."> 194 195 196<meta property="og:image" content="https://media.redcircle.com/images/2026/8/6/15/55b9b431-9341-40d3-a9a2-4282ea86f050_cs_fullsquare.jpg"> 197<meta property="og:image:alt" content="About | Code Story | Startup Podcast for Technical Founders"> 198 199<meta property="og:url" content="https://www.codestory.co/about/"> 200<meta property="og:locale" content="en_US"> 201 202 203 204 205 206<meta name="twitter:card" content="summary_large_image"> 207<meta name="twitter:title" content="About | Code Story | Startup Podcast for Technical Founders"> 208 209<meta name="twitter:description" content="Learn more about Code Story | Startup Podcast for Technical Founders."> 210 211 212<meta name="twitter:image" content="https://media.redcircle.com/images/2026/8/6/15/55b9b431-9341-40d3-a9a2-4282ea86f050_cs_fullsquare.jpg"> 213 214 215 216 217 218<meta name="apple-itunes-app" content="app-id=525463029"> 219 220 221 222
223<script type="application/ld+json"> 224{"@context": "https://schema.org", "@graph": [{"@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Code Story | Startup Podcast for Technical Founders", "item": "https://www.codestory.co/"}, {"@type": "ListItem", "position": 2, "name": "About", "item": "https://www.codestory.co/about/"}]}]} 225</script>
225 226 227 228 229 230 231 <meta name="robots" content="index, follow, max-image-preview:large"> 232 233 234 235 236 237</head> 238<body class="h-full antialiased"> 239 240 241 242 243 244 245 246 247 248 249 250 251 252 <div class="min-h-full"> 253 254 255 256 257 258 259 260 261<nav class="border-b border-theme-border bg-theme-bg"> 262 <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8"> 263 <div class="flex items-center justify-between gap-4 py-4" data-nav-row="rail"> 264 <div class="flex min-w-0 shrink items-center gap-3 md:max-w-xs md:shrink-0" data-nav-brand><div class="h-8 w-1 shrink-0 bg-theme-primary"></div><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/" class="inline-flex items-center"><img src="https://podview-media.nyc3.cdn.digitaloceanspaces.com/podcasts/logos/codestory-logo.png" alt="Code Story | Startup Podcast for Technical Founders" class="h-8 w-auto max-w-48 object-contain"></a></div> 265 <div class="hidden shrink-0 items-center gap-5 text-sm uppercase tracking-[0.1em] md:flex"> 266 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/" class="whitespace-nowrap text-theme-text-muted transition hover:text-theme-text">Home</a> 267 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/episodes/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Episodes</a> 268<details class="group relative shrink-0" data-nav-inline-link data-nav-dropdown> 269 <summary class="whitespace-nowrap text-theme-text-muted transition hover:text-theme-text flex cursor-pointer list-none items-center gap-1 [&::-webkit-details-marker]:hidden"> 270 Browse 271 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-3.5 w-3.5 transition group-open:rotate-180"> 272 <path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /> 273</svg> 274 </summary> 275 <div class="absolute right-0 z-[70] mt-2 max-h-[min(70vh,36rem)] w-80 overflow-y-auto overscroll-contain rounded-xl border border-theme-border bg-theme-surface p-2 text-left normal-case tracking-normal text-theme-text shadow-2xl"> 276 277 <div class=""> 278 279 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tags/" class="flex min-h-10 items-center justify-between rounded-lg px-3 py-2 text-sm font-semibold text-theme-text transition hover:bg-theme-border/50"> 280 Categories 281 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4 text-theme-text-muted"> 282 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 283</svg> 284 </a> 285 286 287 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/product-development/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 288 <span class="min-w-0 truncate">Product Development</span> 289 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">96</span> 290 </a> 291 292 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/engineering-leadership/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text">
293 <span class="min-w-0 truncate">Engineering Leadership</span> 294 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">46</span> 295 </a> 296 297 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/ai-machine-learning/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 298 <span class="min-w-0 truncate">AI & Machine Learning</span> 299 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">79</span> 300 </a> 301 302 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/fintech/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 303 <span class="min-w-0 truncate">Fintech</span> 304 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">54</span> 305 </a> 306 307 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/infrastructure/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 308 <span class="min-w-0 truncate">
308Infrastructure</span> 309 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">46</span> 310 </a> 311 312 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/saas/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 313 <span class="min-w-0 truncate">SaaS</span> 314 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">48</span> 315 </a> 316 317 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/data-engineering/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 318 <span class="min-w-0 truncate">Data Engineering</span> 319 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">64</span> 320 </a> 321 322 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/security-compliance/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 323 <span class="min-w-0 truncate">Security & Compliance</span> 324 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">90</span> 325 </a> 326 327 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/developer-tools/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 328 <span class="min-w-0 truncate">Developer Tools</span> 329 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">68</span> 330 </a> 331 332 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/software-architecture/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 333 <span class="min-w-0 truncate">Software Architecture</span> 334 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">61</span> 335 </a> 336 337 338 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tags/" class="flex min-h-10 items-center gap-1 rounded-lg px-3 py-2 text-sm font-medium text-theme-primary transition hover:bg-theme-border/50"> 339 View all categories 340 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4"> 341 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 342</svg> 343 </a> 344 345 </div> 346 347 <div class="mt-2 border-t border-theme-border pt-2"> 348 349 <p class="px-3 py-2 text-sm font-semibold text-theme-text">Seasons</p> 350 351 352 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-1/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text">
353 <span class="min-w-0 truncate">Season 1</span> 354 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">26</span> 355 </a> 356 357 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-2/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 358 <span class="min-w-0 truncate">Season 2</span> 359 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">27</span> 360 </a> 361 362 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-3/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 363 <span class="min-w-0 truncate">Season 3</span> 364 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">40</span> 365 </a> 366 367 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-4/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 368 <span class="min-w-0 truncate">Season 4</span> 369 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">39</span> 370 </a> 371 372 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-5/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 373 <span class="min-w-0 truncate">Season 5</span> 374 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">85</span> 375 </a> 376 377 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-6/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 378 <span class="min-w-0 truncate">Season 6</span> 379 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">104</span> 380 </a> 381 382 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-7/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 383 <span class="min-w-0 truncate">Season 7</span> 384 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">96</span> 385 </a> 386 387 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-8/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 388 <span class="min-w-0 truncate">Season 8</span> 389 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">103</span> 390 </a> 391 392 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-9/" class="flex min-h-10 items-center justify-between gap-4 roun
392ded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 393 <span class="min-w-0 truncate">Season 9</span> 394 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">69</span> 395 </a> 396 397 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-10/" class="flex min-h-10 items-center justify-between gap-4 rounded-lg px-3 py-2 text-sm font-normal text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text"> 398 <span class="min-w-0 truncate">Season 10</span> 399 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">84</span> 400 </a> 401 402 403 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/episodes/" class="flex min-h-10 items-center gap-1 rounded-lg px-3 py-2 text-sm font-medium text-theme-primary transition hover:bg-theme-border/50"> 404 Episodes 405 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4"> 406 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 407</svg> 408 </a> 409 410 </div> 411 412 </div> 413</details> 414<a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/about/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>About</a><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/contact/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Sponsor the Show</a><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/follow/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Subscribe</a><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/rate/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Rate Show</a><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/guest-intake/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Be a Guest</a><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/blog/" class="shrink-0 whitespace-nowrap text-theme-text-muted transition hover:text-theme-text" data-nav-inline-link>Blog</a> 415 </div> 416 <button type="button" id="rail-menu-toggle" class="flex h-11 w-11 shrink-0 items-center justify-center rounded border border-theme-border text-theme-text-muted transition hover:text-theme-text" aria-expanded="false" aria-controls="rail-menu-panel" aria-haspopup="dialog"> 417 <span class="sr-only">Open menu</span><svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-5 w-5"> 418 <path stroke-linecap="round" stroke-linejoin="round" d="M6.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM12.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0ZM18.75 12a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z" /> 419</svg> 420 </button> 421 </div> 422 </div> 423</nav> 424 425 426<div id="rail-menu-overlay" class="fixed inset-0 z-[60] hidden" aria-hidden="true"> 427 <button type="button" class="absolute inset-0 bg-black/60 backdrop-blur-sm" data-nav-dismiss aria-label="Close navigation"></button> 428 <div id="rail-menu-panel" role="dialog" aria-modal="true" aria-label="Navigation" 429 class="absolute inset-x-0 bottom-0 flex max-h-[80vh] w-full translate-y-full flex-col overflow-hidden rounded-t-2xl border-t border-theme-border bg-theme-surface text-theme-text shadow-2xl transition-transform duration-200 md:inset-y-0 md:left-auto md:right-0 md:max-h-none md:w-96 md:translate-x-full md:translate-y-0 md:rounded-none md:border-l md:border-t-0"> 430 <div class="flex items-center justify-between gap-3 border-b border-theme-border px-5 py-4">
431 <span class="min-w-0 truncate font-heading text-base font-bold text-theme-primary">Code Story | Startup Podcast for Technical Founders</span> 432 <button type="button" class="flex h-11 w-11 shrink-0 items-center justify-center rounded-full text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-dismiss aria-label="Close navigation"> 433 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-5 w-5"> 434 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 435</svg> 436 </button> 437 </div> 438 <div class="min-h-0 flex-1 overflow-y-auto overscroll-contain p-3"> 439 440 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link> 441 Home 442 </a> 443 444 445 446 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/episodes/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="0"> 447 Episodes 448 </a> 449 450 451 452 <div class="py-2 md:hidden" data-nav-overflow-index="1"> 453 <p class="px-4 pb-1 text-xs font-semibold uppercase tracking-[0.14em] text-theme-text-subtle">Browse</p> 454 455 456 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tags/" class="flex min-h-11 items-center justify-between rounded-lg px-4 py-3 text-base font-semibold text-theme-text transition hover:bg-theme-border/50" data-nav-link> 457 Categories 458 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4 text-theme-text-muted"> 459 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 460</svg> 461 </a> 462 463 464 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/product-development/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 465 <span class="min-w-0 truncate">Product Development</span> 466 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">96</span> 467 </a> 468 469 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/engineering-leadership/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 470 <span class="min-w-0 truncate">Engineering Leadership</span> 471 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">46</span> 472 </a> 473 474 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/ai-machine-learning/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 475 <span class="min-w-0 truncate">AI & Machine Learning</span>
476 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">79</span> 477 </a> 478 479 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/fintech/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 480 <span class="min-w-0 truncate">Fintech</span> 481 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">54</span> 482 </a> 483 484 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/infrastructure/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 485 <span class="min-w-0 truncate">
485Infrastructure</span> 486 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">46</span> 487 </a> 488 489 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/saas/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 490 <span class="min-w-0 truncate">SaaS</span> 491 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">48</span> 492 </a> 493 494 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/data-engineering/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 495 <span class="min-w-0 truncate">Data Engineering</span> 496 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">64</span> 497 </a> 498 499 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/security-compliance/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 500 <span class="min-w-0 truncate">Security & Compliance</span> 501 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">90</span> 502 </a> 503 504 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/developer-tools/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 505 <span class="min-w-0 truncate">Developer Tools</span> 506 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">68</span> 507 </a> 508 509 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tag/software-architecture/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 510 <span class="min-w-0 truncate">Software Architecture</span> 511 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">61</span> 512 </a> 513 514 515 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/tags/" class="flex min-h-11 items-center gap-1 rounded-lg px-7 py-2.5 text-sm font-medium text-theme-primary transition hover:bg-theme-border/50" data-nav-link> 516 View all categories 517 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4"> 518 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 519</svg> 520 </a> 521 522 523 524 <p class="px-4 py-3 text-base font-semibold text-theme-text">Seasons</p> 525 526 527 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-1/" class="flex min-h-11 items-center justify-between gap-4 roun
527ded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 528 <span class="min-w-0 truncate">Season 1</span> 529 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">26</span> 530 </a> 531 532 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-2/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 533 <span class="min-w-0 truncate">Season 2</span> 534 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">27</span> 535 </a> 536 537 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-3/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 538 <span class="min-w-0 truncate">Season 3</span> 539 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">40</span> 540 </a> 541 542 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-4/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 543 <span class="min-w-0 truncate">Season 4</span> 544 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">39</span> 545 </a> 546 547 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-5/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 548 <span class="min-w-0 truncate">Season 5</span> 549 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">85</span> 550 </a> 551 552 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-6/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 553 <span class="min-w-0 truncate">Season 6</span> 554 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">104</span> 555 </a> 556 557 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-7/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 558 <span class="min-w-0 truncate">Season 7</span> 559 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">96</span> 560 </a> 561 562 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-8/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 563 <span class="min-w-0 truncate">Season 8</span>
564 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">103</span> 565 </a> 566 567 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-9/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 568 <span class="min-w-0 truncate">Season 9</span> 569 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">69</span> 570 </a> 571 572 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/season/season-10/" class="flex min-h-11 items-center justify-between gap-4 rounded-lg px-7 py-2.5 text-sm text-theme-text-muted transition hover:bg-theme-border/50 hover:text-theme-text" data-nav-link> 573 <span class="min-w-0 truncate">Season 10</span> 574 <span class="shrink-0 tabular-nums text-xs text-theme-text-subtle">84</span> 575 </a> 576 577 578 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/episodes/" class="flex min-h-11 items-center gap-1 rounded-lg px-7 py-2.5 text-sm font-medium text-theme-primary transition hover:bg-theme-border/50" data-nav-link> 579 Episodes 580 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-4 w-4"> 581 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 582</svg> 583 </a> 584 585 586 </div> 587 588 589 590 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/about/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="2"> 591 About 592 </a> 593 594 595 596 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/contact/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="3"> 597 Sponsor the Show 598 </a> 599 600 601 602 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/follow/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="4"> 603 Subscribe 604 </a> 605 606 607 608 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/rate/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="5"> 609 Rate Show 610 </a> 611 612 613 614 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/guest-intake/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="6"> 615 Be a Guest 616 </a> 617 618 619 620 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/blog/" class="flex min-h-11 items-center rounded-lg px-4 py-3 text-base font-medium text-theme-text transition hover:bg-theme-border/50 md:hidden" data-nav-link data-nav-overflow-index="7"> 621 Blog 622 </a> 623 624 625 </div> 626 </div> 627</div>
628<script> 629(function () { 630 const toggle = document.getElementById('rail-menu-toggle'); 631 const overlay = document.getElementById('rail-menu-overlay'); 632 const panel = document.getElementById('rail-menu-panel'); 633 const row = document.querySelector('[data-nav-row="rail"]'); 634 if (!toggle || !overlay || !panel || !row) return; 635 636 // The toggle carries `flex`, and an author-stylesheet class beats the UA's 637 // [hidden] rule â setting the hidden property leaves it on screen, opening an 638 // empty drawer. Inline style is the only form that wins here. 639 function setToggleVisible(visible) { 640 toggle.style.display = visible ? '' : 'none'; 641 } 642 643 function syncOverflow() { 644 const inlineLinks = [...row.querySelectorAll('[data-nav-inline-link]')]; 645 const overflowLinks = [...panel.querySelectorAll('[data-nav-overflow-index]')]; 646 inlineLinks.forEach((link) => { link.hidden = false; }); 647 overflowLinks.forEach((link) => { link.classList.add('md:hidden'); }); 648 649 if (!window.matchMedia('(min-width: 768px)').matches) { 650 setToggleVisible(true); 651 return; 652 } 653 654 setToggleVisible(false); 655 for (let index = inlineLinks.length - 1; row.scrollWidth > row.clientWidth && index >= 0; index -= 1) { 656 inlineLinks[index].hidden = true; 657 overflowLinks[index]?.classList.remove('md:hidden'); 658 setToggleVisible(true); 659 } 660 } 661 662 function openMenu() { 663 overlay.classList.remove('hidden'); 664 overlay.setAttribute('aria-hidden', 'false'); 665 toggle.setAttribute('aria-expanded', 'true'); 666 document.body.style.overflow = 'hidden'; 667 requestAnimationFrame(() => { 668 panel.classList.remove('translate-y-full'); 669 panel.classList.remove('md:translate-x-full'); 670 const firstVisibleLink = [...panel.querySelectorAll('[data-nav-link]')] 671 .find((link) => link.offsetParent !== null); 672 firstVisibleLink?.focus(); 673 }); 674 } 675 676 function closeMenu() { 677 panel.classList.add('translate-y-full'); 678 panel.classList.add('md:translate-x-full'); 679 toggle.setAttribute('aria-expanded', 'false'); 680 overlay.setAttribute('aria-hidden', 'true'); 681 document.body.style.overflow = ''; 682 window.setTimeout(() => overlay.classList.add('hidden'), 200); 683 toggle.focus(); 684 } 685 686 // The panel says aria-modal, so focus has to actually stay inside it. 687 function focusables() { 688 return [...panel.querySelectorAll('a[href], button')].filter((el) => el.offsetParent !== null); 689 } 690 691 toggle.addEventListener('click', openMenu); 692 overlay.querySelectorAll('[data-nav-dismiss]').forEach((element) => element.addEventListener('click', closeMenu)); 693 window.addEventListener('keydown', (event) => { 694 if (toggle.getAttribute('aria-expanded') !== 'true') return; 695 if (event.key === 'Escape') { 696 closeMenu(); 697 return; 698 } 699 if (event.key !== 'Tab') return; 700 701 const items = focusables(); 702 if (!items.length) return; 703 const first = items[0]; 704 const last = items[items.length - 1]; 705 if (!panel.contains(document.activeElement)) { 706 event.preventDefault(); 707 first.focus(); 708 } else if (event.shiftKey && document.activeElement === first) { 709 event.preventDefault(); 710 last.focus(); 711 } else if (!event.shiftKey && document.activeElement === last) { 712 event.preventDefault(); 713 first.focus(); 714 } 715 }); 716 // The Browse menu is a native <details>, so nothing closes it on its own: a 717 // click elsewhere, Escape, or a boosted page swap that keeps this nav in the 718 // DOM would all leave the panel hanging open over the new page. 719 function closeDropdowns(except) { 720 row.querySelectorAll('[data-nav-dropdown][open]').forEach((dropdown) => { 721 if (dropdown !== except) dropdown.open = false; 722 }); 723 } 724 725 document.addEventListener('click', (event) => { 726 const inside = event.target.closest?.('[data-nav-dropdown]'); 727 closeDropdowns(inside && row.contains(inside) ? inside : null); 728 }); 729 window.addEventListener('keydown', (event) => { 730 if (event.key !== 'Escape') return; 731 const open = row.querySelector('[data-nav-dropdown][open]'); 732 if (!open) return; 733 open.open = false;
734 open.querySelector('summary')?.focus(); 735 }); 736 document.body.addEventListener('htmx:beforeSwap', () => closeDropdowns(null)); 737 738 // Crossing a breakpoint can reveal links whose final font/image dimensions 739 // settle after the resize callback. Refit when the rendered row changes, 740 // including its children: the row itself can stay the same width while its 741 // links grow and push the menu button out of view. 742 let overflowFrame = null; 743 function scheduleOverflow() { 744 if (overflowFrame !== null) return; 745 overflowFrame = requestAnimationFrame(() => { 746 overflowFrame = null; 747 syncOverflow(); 748 }); 749 } 750 if (window.ResizeObserver) { 751 const observer = new ResizeObserver(scheduleOverflow); 752 observer.observe(row); 753 [...row.children].forEach((child) => observer.observe(child)); 754 } 755 window.addEventListener('resize', scheduleOverflow); 756 document.fonts?.addEventListener('loadingdone', scheduleOverflow); 757 document.fonts?.ready.then(scheduleOverflow); 758 syncOverflow(); 759})(); 760</script>
760 761 762 763<style data-pv-player-offset> 764 /* A FLOW SPACER, not `padding-bottom` on the body. `<body class="h-full">` is 765 `height: 100%` and Tailwind's preflight makes everything `border-box`, so 766 body padding is consumed by that fixed height and reserves exactly nothing â 767 the footer's last link sat under the bar with a 157px "reserve" in the 768 computed styles. Found in browser QA; it also silently defeated `floating`'s 769 own 6rem mobile clearance, which had shipped that way. A block-level ::after 770 is a real child in normal flow, so it extends the scrollable content. */ 771 body::after { 772 content: ""; 773 display: block; 774 height: var(--pv-player-offset, 0px); 775 /* Matches the bar's own 200ms rise, so the page does not jolt open under it. */ 776 transition: height 200ms ease-out; 777 } 778 @media (prefers-reduced-motion: reduce) { 779 body::after { transition: none; } 780 } 781 782</style> 783 784 785 786 787 788 789 <main id="pv-public-content" tabindex="-1" hx-history-elt> 790 791<div class="mx-auto max-w-4xl px-4 py-12 sm:px-6 lg:px-8"> 792 <article class="bg-theme-surface rounded-xl shadow-sm border border-theme-border overflow-hidden"> 793 <div class="p-6 sm:p-8"> 794 <div class="flex flex-col sm:flex-row gap-8"> 795 796 797 798<img src="https://media.redcircle.com/images/2026/8/6/15/55b9b431-9341-40d3-a9a2-4282ea86f050_cs_fullsquare.jpg" alt="Code Story | Startup Podcast for Technical Founders" width="512" height="512" loading="lazy" decoding="async" 799 class="h-48 w-48 rounded-xl shrink-0 object-cover "> 800 801 802 803 804 805 <div> 806 <h1 class="text-3xl font-bold text-theme-text font-heading">About Code Story | Startup Podcast for Technical Founders</h1> 807 808 <p class="mt-2 text-lg text-theme-text-muted">Hosted by Noah Labhart | Technical Founder & Startup Mentor</p> 809 810 </div> 811 </div> 812 813 <div class="mt-8 prose max-w-none text-theme-text prose-headings:text-theme-text prose-p:text-theme-text prose-a:text-theme-primary"> 814 Code Story is a startup podcast for technical founders building and scaling software products. Each episode features SaaS founders, engineers, and product leaders sharing how they built their product, found product-market fit, and navigated early-stage growth. We explore: 815<ul><li>Early engineering decisions and MVP development</li><li>Landing the first customers</li><li>Pricing and go-to-market experiments</li><li>Scaling challenges and infrastructure bottlenecks</li><li>Hiring the first team</li><li>Lessons learned from growing a startup</li></ul><p>From first commit to first scale, Code Story focuses on the critical transition from building software to building a scalable business.</p><p>If youâre a founder, engineer, or product leader interested in SaaS, startups, and scaling technology companies, this podcast breaks down how great products are built â and how they grow.</p> 816 </div> 817 818 819 <div class="mt-8"> 820 <h2 class="text-xl font-semibold text-theme-text font-heading mb-4"> 821 Your Host 822 </h2> 823 <div class="grid gap-6 sm:grid-cols-2"> 824 825 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/guests/noah-labhart-startup-founder-cto-1/" 826 class="group flex items-start gap-4 p-4 rounded-lg bg-theme-border/30 hover:bg-theme-border/50 transition"> 827 828 829 830 831 832 833<img src="https://podview-media.nyc3.cdn.digitaloceanspaces.com/guests/1160/headshots/1437.jpg" alt="Noah Labhart - Startup Founder & CTO" width="128" height="128" loading="lazy" decoding="async" 834 class="h-16 w-16 rounded-full shrink-0 object-cover "> 835 836 837 838 839 840 841 842 843 <div class="min-w-0 flex-1"> 844 <h3 class="font-semibold text-theme-text group-hover:text-theme-primary transition">Noah Labhart - Startup Founder & CTO</h3> 845 846 <p class="mt-1 text-sm text-theme-text-muted line-clamp-2">
846Startup founder. CTO. Podcast Host. Software Architect. Husband. Father. Jesus Follower.</p> 847 848 </div> 849 </a> 850 851 </div> 852 </div> 853 854 855 856 857 858 859 860 861 <div class="mt-8"> 862 <h2 class="text-xl font-semibold text-theme-text font-heading mb-4">Listen on</h2> 863 <div class="flex flex-wrap gap-3"> 864 865 <a href="https://podcasts.apple.com/podcast/id1466861744" target="_blank" rel="noopener" 866 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 867 Apple Podcasts 868 </a> 869 870 <a href="https://open.spotify.com/show/0f5HGQ2EPd63H83gqAifXp" target="_blank" rel="noopener" 871 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 872 Spotify 873 </a> 874 875 <a href="https://pca.st/itunes/1466861744" target="_blank" rel="noopener" 876 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 877 Pocket Casts 878 </a> 879 880 <a href="https://castbox.fm/vic/1466861744" target="_blank" rel="noopener" 881 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 882 Castbox 883 </a> 884 885 <a href="https://youtube.com/@codestorypodcast" target="_blank" rel="noopener" 886 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 887 YouTube 888 </a> 889 890 <a href="https://player.fm/series/code-story-insights-from-startup-tech-leaders-2518264" target="_blank" rel="noopener" 891 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 892 Player FM 893 </a> 894 895 <a href="https://overcast.fm/itunes1466861744" target="_blank" rel="noopener" 896 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 897 Overcast 898 </a> 899 900 <a href="https://castro.fm/itunes/1466861744" target="_blank" rel="noopener" 901 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 902 Castro 903 </a> 904 905 <a href="https://www.goodpods.com/podcasts-aid/1466861744" target="_blank" rel="noopener" 906 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 907 Goodpods 908 </a> 909 910 <a href="https://moon.fm/itunes/1466861744" target="_blank" rel="noopener" 911 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 912 Moon FM 913 </a> 914 915 <a href="https://www.podbean.com/itunes/1466861744" target="_blank" rel="noopener" 916 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 917 Podbean 918 </a> 919 920 <a href="https://podcastaddict.com/feed/https%3A%2F%2Frss.introcast.io%2F1466861744%2Ffeeds.redcircle.com%2Fac5e79a4-0405-49a3-af2c-02c37f0b3879" target="_blank" rel="noopener" 921 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 922 Podcast Addict 923 </a> 924 925 <a href="https://www.podcastrepublic.net/podcast/1466861744" target="_blank" rel="noopener" 926 class="inline-flex items-center px-4 py-2 rounded-lg bg-theme-border text-theme-text hover:bg-theme-primary hover:text-theme-bg transition"> 927 Podcast Republic 928 </a> 929 930 </div> 931 </div> 932 933 </div> 934 </article> 935</div> 936 937 938 939 940 941 942 943 944 945 946 947
947<script id="pv-boost-head" type="application/json">{"canonical": "https://www.codestory.co/about/", "description": "Learn more about Code Story | Startup Podcast for Technical Founders. Code Story is a startup podcast for technical founders building and scaling software products....", "og": {"title": "About | Code Story | Startup Podcast for Technical Founders", "description": "Learn more about Code Story | Startup Podcast for Technical Founders.", "image": "https://media.redcircle.com/images/2026/8/6/15/55b9b431-9341-40d3-a9a2-4282ea86f050_cs_fullsquare.jpg", "url": "https://www.codestory.co/about/", "type": "website"}, "twitter": {"title": "About | Code Story | Startup Podcast for Technical Founders", "description": "Learn more about Code Story | Startup Podcast for Technical Founders.", "image": "https://media.redcircle.com/images/2026/8/6/15/55b9b431-9341-40d3-a9a2-4282ea86f050_cs_fullsquare.jpg"}}</script>
947 948 </main> 949 950 951 952 953 954 955 956 957 958<footer class="relative mt-auto overflow-hidden border-t border-theme-border bg-theme-surface"> 959 <div class="pointer-events-none absolute inset-x-0 top-0 h-px bg-theme-primary/40" aria-hidden="true"></div> 960 961 <div class="relative mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8"> 962 963 <div class="text-center"> 964 <p class="font-heading text-4xl font-bold leading-[1.05] tracking-tight text-theme-text sm:text-5xl"> 965 Code Story | Startup Podcast for Technical Founders 966 </p> 967 <p class="mx-auto mt-4 max-w-xl text-sm leading-relaxed text-theme-text-muted sm:text-base"> 968 Code Story is a startup podcast for technical founders building and scaling software products. Each episode features SaaS founders, engineers, and product leaders sharing how they built their ⦠969 </p> 970 971 <div class="mt-6 flex justify-center"> 972 973 974 975 976<div class="flex items-center gap-3 justify-center"> 977 978 <a href="https://www.linkedin.com/company/code-story" target="_blank" rel="noopener noreferrer" 979 class="tap-target-mobile justify-center text-theme-text-muted hover:text-theme-primary transition " 980 aria-label="LinkedIn"> 981 982 983<svg class="w-5 h-5" fill="currentColor" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg> 984 985 986 </a> 987 988 <a href="https://stacks.codestory.co" target="_blank" rel="noopener noreferrer" 989 class="tap-target-mobile justify-center text-theme-text-muted hover:text-theme-primary transition " 990 aria-label="Other"> 991 992 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 993 <path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" /> 994</svg> 995 996 </a> 997 998 <a href="https://www.youtube.com/@codestorypodcast" target="_blank" rel="noopener noreferrer" 999 class="tap-target-mobile justify-center text-theme-text-muted hover:text-theme-primary transition " 1000 aria-label="YouTube"> 1001 1002 <svg class="w-5 h-5" fill="currentColor" aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.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> 1003 1004 1005 </a> 1006 1007</div> 1008 1009 1010 </div> 1011 1012 </div> 1013 1014 1015 <nav class="mt-10 flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-sm font-medium"> 1016 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/" class="tap-target-mobile text-theme-text transition-colors hover:text-theme-primary">Home</a> 1017 <span aria-hidden="true" class="hidden h-3 w-px bg-theme-border sm:block"></span><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/episodes/" class="tap-target-mobile text-theme-text transition-colors hover:text-theme-primary">Episodes</a>
1018 <span aria-hidden="true" class="hidden h-3 w-px bg-theme-border sm:block"></span><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/about/" class="tap-target-mobile text-theme-text transition-colors hover:text-theme-primary">About</a> 1019 <span aria-hidden="true" class="hidden h-3 w-px bg-theme-border sm:block"></span><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/follow/" class="tap-target-mobile text-theme-text transition-colors hover:text-theme-primary">Subscribe</a> 1020 <span aria-hidden="true" class="hidden h-3 w-px bg-theme-border sm:block"></span><a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/blog/" class="tap-target-mobile text-theme-text transition-colors hover:text-theme-primary">Blog</a> 1021 1022 1023 1024 </nav> 1025 1026 1027 1028 <div class="mt-8 flex flex-wrap items-center justify-center gap-2"> 1029 1030 <a href="https://podcasts.apple.com/podcast/id1466861744" target="_blank" rel="noopener" 1031 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1032 1033 1034 1035<img src="/static/images/platform-logos/apple.81fb483bafac.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1036 1037 1038 <span>Apple Podcasts</span> 1039 </a> 1040 1041 <a href="https://open.spotify.com/show/0f5HGQ2EPd63H83gqAifXp" target="_blank" rel="noopener" 1042 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1043 1044 1045 1046<img src="/static/images/platform-logos/spotify.14dc2fed5342.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1047 1048 1049 <span>Spotify</span> 1050 </a> 1051 1052 <a href="https://pca.st/itunes/1466861744" target="_blank" rel="noopener" 1053 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1054 1055 1056 1057<img src="/static/images/platform-logos/pocketcasts.7da8fbe40791.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1058 1059 1060 <span>Pocket Casts</span> 1061 </a> 1062 1063 <a href="https://castbox.fm/vic/1466861744" target="_blank" rel="noopener" 1064 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1065 1066 1067 1068<img src="/static/images/platform-logos/castbox.b6404094c983.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1069 1070 1071 <span>Castbox</span> 1072 </a> 1073 1074 <a href="https://youtube.com/@codestorypodcast" target="_blank" rel="noopener" 1075 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1076 1077 1078 1079<img src="/static/images/platform-logos/youtube.df28de465728.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1080 1081 1082 <span>YouTube</span> 1083 </a> 1084 1085 <a href="https://player.fm/series/code-story-insights-from-startup-tech-leaders-2518264" target="_blank" rel="noopener" 1086 class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg/50 px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1087 1088 1089 1090<img src="/static/images/platform-logos/playerfm.f686436e9b2f.svg" alt="" class="w-3.5 h-3.5 rounded shrink-0" loading="lazy"> 1091 1092
1093 <span>Player FM</span> 1094 </a> 1095 1096 1097 1098<a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/follow/" class="tap-target-mobile inline-flex items-center gap-1.5 rounded-full border border-theme-border bg-theme-bg px-3 py-1.5 text-xs text-theme-text-muted transition-colors hover:border-theme-primary hover:text-theme-primary"> 1099 <span>All listening apps</span> 1100 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="h-3.5 w-3.5 shrink-0"> 1101 <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" /> 1102</svg> 1103</a> 1104 1105 1106 </div> 1107 1108 1109 1110 1111 1112 1113<div class="newsletter-footer newsletter-footer--standard mt-8 pt-8 border-t border-theme-border"> 1114 <div class="flex flex-col sm:flex-row sm:items-center gap-4"> 1115 <div class="flex-1"> 1116 <h2 class="text-sm font-semibold text-theme-text tracking-wide"> 1117 1118 Get Podcast Updates and Exclusive Content 1119 1120 </h2> 1121 </div> 1122 1123 <form method="post" 1124 action="/email-signup/" 1125 hx-post="/email-signup/" 1126 hx-headers='{"X-CSRFToken": "oJdhjbMvAOuYsYCx7ug3T50x4ZjIaAbH5Xrz07GqA7G4Q9BvHcWeImpOzn4ONy0r"}' 1127 hx-target="this" 1128 hx-swap="outerHTML" 1129 class="flex w-full flex-col items-stretch gap-2 sm:w-auto sm:flex-row"> 1130 <input type="hidden" name="csrfmiddlewaretoken" value="oJdhjbMvAOuYsYCx7ug3T50x4ZjIaAbH5Xrz07GqA7G4Q9BvHcWeImpOzn4ONy0r"> 1131 <input type="hidden" name="source" value="footer"> 1132 1133<!-- email-signup-bot-fields:start --> 1134<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;"> 1135 <label> 1136 Website 1137 <input type="text" 1138 name="website" 1139 value="" 1140 tabindex="-1" 1141 autocomplete="off"> 1142 </label> 1143</div> 1144<input type="hidden" name="signup_timing_token" value="eyJpc3N1ZWRfYXQiOjE3OTA5MTcxOTcuMjg4NzAyNX0:1xCVNF:q3WMHk43GGMopDaZY4kz3BWRl0nIDe0piDzwGt5Cods"> 1145 1146<input type="hidden" name="cf-turnstile-response" value=""> 1147 1148<iframe class="email-signup-turnstile-frame" 1149 data-src="https://podview.com/_turnstile/email-signup/?embed=Imh0dHBzOi8vd3d3LmNvZGVzdG9yeS5jbyI%3A1xCVNF%3A15wmHC8bGy9KX9Dzpv3TIMeFLt5t1Ne8wulgP7JjYpc" 1150 title="Security verification" 1151 scrolling="no" 1152 style="position:absolute;width:1px;height:1px;border:0;clip-path:inset(50%);overflow:hidden;"></iframe> 1153 1154<p class="email-signup-challenge-error w-full text-xs text-theme-text-muted" role="alert" hidden>Verification couldn't load. Please refresh and try again.</p> 1155 1156<!-- email-signup-bot-fields:end --> 1157 1158 1159 <input type="text" 1160 name="name" 1161 autocomplete="given-name" 1162 maxlength="100" 1163 aria-label="First name" 1164 placeholder="First name" 1165 class="h-11 min-w-0 w-full border border-theme-border bg-theme-bg px-4 text-sm text-theme-text transition placeholder:text-theme-text-muted focus:outline-none focus-visible:border-theme-primary focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-theme-primary sm:w-40"> 1166 1167 <input type="email" 1168 name="email" 1169 required 1170 autocomplete="email" 1171 aria-label="Email address" 1172 placeholder="Enter your email" 1173 class="h-11 min-w-0 w-full border border-theme-border bg-theme-bg px-4 text-sm text-theme-text transition placeholder:text-theme-text-muted focus:outline-none focus-visible:border-theme-primary focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-theme-primary sm:w-64 sm:flex-1"> 1174 <button type="submit" 1175 class="h-11 w-full whitespace-nowrap border border-theme-primary bg-theme-primary px-5 text-sm font-semibold text-theme-bg transition hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-theme-bg sm:w-auto"> 1176 Subscribe 1177 </button> 1178 </form> 1179 </div> 1180</div> 1181 1182 1183 </div> 1184 1185 1186 <div class="relative border-t border-theme-border bg-theme-bg"> 1187 <div class="mx-auto flex max-w-7xl flex-col items-start justify-between gap-2 px-4 py-4 text-xs text-theme-text-subtle sm:flex-row sm:items-center sm:px-6 lg:px-8"> 1188 1189 1190 1191 1192<p>© Code Story | Startup Podcast for Technical Founders. </p> 1193<a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/privacy/" class="tap-target-mobile hover:text-theme-primary transition">Privacy Policy</a> 1194 1195 </div> 1196 </div> 1197</footer> 1198 1199 1200 1201 </div> 1202 1203 1204 1205 1206 1207 1208<div id="newsletter-popup" 1209 class="fixed inset-0 z-50 flex items-center justify-center p-4" 1210 style="display: none;" 1211 data-trigger="timed" 1212 data-delay="45" 1213 data-scroll="50" 1214 data-cooldown="72"
1215 data-podcast="codestory"> 1216 1217 1218 <div class="absolute inset-0 bg-black/60 backdrop-blur-sm" onclick="dismissPopup()"></div> 1219 1220 1221 <div class="relative w-full max-w-md bg-theme-surface border border-theme-border shadow-2xl"> 1222 1223 <button onclick="dismissPopup()" 1224 class="absolute top-4 right-4 text-theme-text-muted hover:text-theme-text transition p-1" 1225 aria-label="Close"> 1226 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1227 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 1228</svg> 1229 </button> 1230 1231 <div class="p-6 sm:p-8"> 1232 1233 1234 <h2 class="text-2xl font-bold text-theme-text font-heading tracking-tight mb-2"> 1235 Want to know about future episodes? 1236 </h2> 1237 1238 1239 1240 <p class="text-theme-text-muted mb-6">The best way to follow episodes is to subscribe on your favorite pod-catcher (Spotify, Apple Podcasts, etc.). The second best way? Subscribe to our updates, and we will notify you when new episodes drop.</p> 1241 1242 1243 1244 1245 <div class="mb-6 p-4 border border-theme-primary/20 bg-theme-primary/5"> 1246 <div class="flex items-start gap-3"> 1247 <div class="flex-shrink-0 w-10 h-10 flex items-center justify-center bg-theme-primary/10 text-theme-primary"> 1248 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1249 <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m.75 12 3 3m0 0 3-3m-3 3v-6m-1.5-9H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" /> 1250</svg> 1251 </div> 1252 <div> 1253 <p class="text-sm font-semibold text-theme-text">Want to see some takeaways from Season 12?</p> 1254 1255 <p class="text-xs text-theme-text-muted mt-1">Season 12 contained great insights from CTO's and tech leaders in the startup space. Fill out this form to get â¦</p> 1256 1257 </div> 1258 </div> 1259 </div> 1260 1261 1262 1263 <form id="popup-signup-form" 1264 method="post" 1265 action="/email-signup/" 1266 hx-post="/email-signup/" 1267 hx-headers='{"X-CSRFToken": "oJdhjbMvAOuYsYCx7ug3T50x4ZjIaAbH5Xrz07GqA7G4Q9BvHcWeImpOzn4ONy0r"}' 1268 hx-target="#popup-form-container" 1269 hx-swap="innerHTML" 1270 class="space-y-3"> 1271 <input type="hidden" name="csrfmiddlewaretoken" value="oJdhjbMvAOuYsYCx7ug3T50x4ZjIaAbH5Xrz07GqA7G4Q9BvHcWeImpOzn4ONy0r"> 1272 <input type="hidden" name="source" value="popup"> 1273 1274<!-- email-signup-bot-fields:start --> 1275<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;"> 1276 <label> 1277 Website 1278 <input type="text" 1279 name="website" 1280 value="" 1281 tabindex="-1" 1282 autocomplete="off"> 1283 </label> 1284</div> 1285<input type="hidden" name="signup_timing_token" value="eyJpc3N1ZWRfYXQiOjE3OTA5MTcxOTcuMjg4NzAyNX0:1xCVNF:q3WMHk43GGMopDaZY4kz3BWRl0nIDe0piDzwGt5Cods"> 1286 1287<input type="hidden" name="cf-turnstile-response" value=""> 1288 1289<iframe class="email-signup-turnstile-frame" 1290 data-src="https://podview.com/_turnstile/email-signup/?embed=Imh0dHBzOi8vd3d3LmNvZGVzdG9yeS5jbyI%3A1xCVNF%3A15wmHC8bGy9KX9Dzpv3TIMeFLt5t1Ne8wulgP7JjYpc" 1291 title="Security verification" 1292 scrolling="no" 1293 style="position:absolute;width:1px;height:1px;border:0;clip-path:inset(50%);overflow:hidden;"></iframe> 1294 1295<p class="email-signup-challenge-error w-full text-xs text-theme-text-muted" role="alert" hidden>Verification couldn't load. Please refresh and try again.</p> 1296 1297<!-- email-signup-bot-fields:end --> 1298 1299 1300 <div id="popup-form-container"> 1301 1302 <input type="text" 1303 name="name" 1304 autocomplete="given-name" 1305 maxlength="100" 1306 aria-label="First name" 1307 placeholder="First name" 1308 class="w-full mb-3 px-4 py-3 bg-theme-bg border border-theme-border text-theme-text transition placeholder:text-theme-text-muted focus:outline-none focus-visible:border-theme-primary focus-visible:ring-2 focus-visible:ring-theme-primary focus-visible:ring-offset-2 focus-visible:ring-offset-theme-bg"> 1309 1310 <input type="email" 1311 name="email" 1312 required 1313 autocomplete="email" 1314 aria-label="Email address" 1315 placeholder="Enter your email" 1316 class="w-full px-4 py-3 bg-theme-bg border border-theme-border text-theme-text transition placeholder:text-theme-text-muted focus:outline-none focus-visible:border-theme-primary focus-visible:ring-2 focus-visible:ring-theme-primary focus-visible:ring-offset-2 focus-visible:ring-offset-theme-bg"> 1317 <button type="submit" 1318 class="w-full mt-3 px-5 py-3 bg-theme-primary text-theme-bg font-semibold hover:opacity-90 transition focus:outline-none focus-visible:ring-2 focus-visible:ring-theme-primary focus-visible:ring-offset-2 focus-visible:ring-offset-theme-bg"> 1319 Subscribe 1320 </button> 1321 </div> 1322 </form> 1323 1324 1325 <p class="text-xs text-theme-text-subtle text-center mt-4"> 1326 We respect your privacy. Unsubscribe at any time. 1327 </p> 1328 </div> 1329 </div> 1330</div> 1331
1332<script> 1333(function() { 1334 const popup = document.getElementById('newsletter-popup'); 1335 if (!popup) return; 1336 1337 const trigger = popup.dataset.trigger; 1338 const delaySeconds = parseInt(popup.dataset.delay) || 5; 1339 const scrollPercentage = parseInt(popup.dataset.scroll) || 50; 1340 const cooldownHours = parseInt(popup.dataset.cooldown) || 24; 1341 const podcastSlug = popup.dataset.podcast; 1342 1343 const storageKey = `podview_popup_dismissed_${podcastSlug}`; 1344 1345 // Check cooldown 1346 function shouldShowPopup() { 1347 const dismissedAt = localStorage.getItem(storageKey); 1348 if (!dismissedAt) return true; 1349 1350 const dismissedTime = parseInt(dismissedAt); 1351 const cooldownMs = cooldownHours * 60 * 60 * 1000; 1352 const now = Date.now(); 1353 1354 return (now - dismissedTime) > cooldownMs; 1355 } 1356 1357 // Show popup 1358 function showPopup() { 1359 if (!shouldShowPopup()) return; 1360 popup.style.display = 'flex'; 1361 document.body.style.overflow = 'hidden'; 1362 } 1363 1364 // Dismiss popup and record timestamp 1365 window.dismissPopup = function() { 1366 popup.style.display = 'none'; 1367 document.body.style.overflow = ''; 1368 localStorage.setItem(storageKey, Date.now().toString()); 1369 }; 1370 1371 // Also dismiss on successful signup 1372 document.addEventListener('htmx:afterSwap', function(evt) { 1373 if (evt.detail.target.id === 'popup-form-container') { 1374 // Signup succeeded, set cooldown 1375 localStorage.setItem(storageKey, Date.now().toString()); 1376 // Close popup after showing success message 1377 setTimeout(function() { 1378 popup.style.display = 'none'; 1379 document.body.style.overflow = ''; 1380 }, 3000); 1381 } 1382 }); 1383 1384 // Escape key to close 1385 document.addEventListener('keydown', function(e) { 1386 if (e.key === 'Escape' && popup.style.display === 'flex') { 1387 dismissPopup(); 1388 } 1389 }); 1390 1391 // Trigger setup 1392 if (!shouldShowPopup()) return; 1393 1394 if (trigger === 'exit_intent') { 1395 let triggered = false; 1396 document.addEventListener('mouseout', function(e) { 1397 if (triggered) return; 1398 if (!e.toElement && !e.relatedTarget && e.clientY < 10) { 1399 triggered = true; 1400 showPopup(); 1401 } 1402 }); 1403 } else if (trigger === 'timed') { 1404 setTimeout(showPopup, delaySeconds * 1000); 1405 } else if (trigger === 'scroll') { 1406 let triggered = false; 1407 window.addEventListener('scroll', function() { 1408 if (triggered) return; 1409 const scrollPercent = (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100; 1410 if (scrollPercent >= scrollPercentage) { 1411 triggered = true; 1412 showPopup(); 1413 } 1414 }); 1415 } 1416})(); 1417</script>
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444<style> 1445 /* ---- Surface -------------------------------------------------------- */ 1446 .pv-pp { 1447 position: fixed; 1448 inset-inline: 0; 1449 bottom: 0; 1450 z-index: 45; 1451 background: var(--color-background); 1452 border-top: 1px solid color-mix(in srgb, var(--color-text) 18%, var(--color-background)); 1453 color: var(--color-text); 1454 font-family: var(--font-body); 1455 /* Reserve the device's bottom inset so the rail never sits under the 1456 iOS home indicator. */ 1457 padding-bottom: env(safe-area-inset-bottom, 0px); 1458 box-shadow: 0 -8px 30px -24px color-mix(in srgb, var(--color-text) 60%, transparent); 1459 } 1460 1461 /* The bar is fixed, so it occludes whatever sits at the bottom of the document. 1462 The clearance that fixes that is NOT here â it is the `body::after` flow spacer 1463 in `nav/_player_offset.html`, which every nav style includes and 1464 `test_nav_templates.py` asserts over the nav registry. 1465 1466 There was briefly a `.pv-pp-spacer` div here as well. Two independent fixes for 1467 the same "footer sits under the bar" bug, both body-level children reserving the 1468 same `--pv-player-offset`, so pressing play reserved TWICE the bar height (and on 1469 mobile + `floating`, twice on top of that nav's own 6rem). One contract, one 1470 spacer: keep the one the nav registry is tested against. */ 1471 1472 /* Slide up from the bottom edge on first play. The element is display:none 1473 until JS reveals it, so the animation only ever runs on a real open. */ 1474 @keyframes pv-pp-rise { 1475 from { transform: translateY(100%); } 1476 to { transform: translateY(0); } 1477 } 1478 .pv-pp[data-animate="in"] { 1479 animation: pv-pp-rise 200ms ease-out both; 1480 } 1481 @keyframes pv-pp-sheet { 1482 from { transform: translateY(24px); opacity: 0.6; } 1483 to { transform: translateY(0); opacity: 1; } 1484 } 1485 1486 /* ---- Bar layout ----------------------------------------------------- */ 1487 .pv-pp-bar { 1488 display: flex; 1489 align-items: center; 1490 gap: 0.75rem; 1491 padding: 0.5rem 0.75rem; 1492 min-height: 60px; 1493 } 1494 @media (min-width: 640px) { 1495 .pv-pp-bar { gap: 1rem; padding: 0.625rem 1rem; } 1496 } 1497 1498 /* Every control keeps its intrinsic width. The public <body> inherits 1499 `overflow-wrap: anywhere`, which otherwise shatters short labels like 1500 "1.5x" and "-15" mid-word once flex squeezes them. */ 1501 .pv-pp-bar button, 1502 .pv-pp-time, 1503 .pv-pp-chapter, 1504 .pv-pp-speed { 1505 flex-shrink: 0; 1506 white-space: nowrap; 1507 } 1508 1509 /* ---- Touch targets --------------------------------------------------- */ 1510 .pv-pp-btn { 1511 display: inline-flex; 1512 align-items: center; 1513 justify-content: center; 1514 min-width: 44px; 1515 min-height: 44px; 1516 border-radius: 0.5rem; 1517 color: color-mix(in srgb, var(--color-text) 70%, var(--color-background)); 1518 transition: color 150ms ease, background-color 150ms ease; 1519 } 1520 .pv-pp-btn:hover { 1521 color: var(--color-primary); 1522 background: color-mix(in srgb, var(--color-text) 8%, transparent); 1523 } 1524 .pv-pp-btn:focus-visible { 1525 outline: 2px solid var(--color-primary); 1526 outline-offset: 2px; 1527 } 1528 .pv-pp-play { 1529 width: 44px; 1530 height: 44px; 1531 border-radius: 9999px; 1532 background: var(--color-primary); 1533 color: var(--color-background); 1534 } 1535 .pv-pp-play:hover { 1536 background: var(--color-primary); 1537 /* Restate the colour. `.pv-pp-btn:hover` sets `color: var(--color-primary)`, 1538 which is right for the ghost buttons sitting on the bar's own surface and 1539 catastrophic for this one: the play/pause button's BACKGROUND is 1540 --color-primary, so inheriting that hover colour painted the glyph in the 1541 same colour as the disc under it and the icon vanished on hover â on every 1542 theme, because both sides of the collision are the same token. */ 1543 color: var(--color-background); 1544 opacity: 0.9; 1545 } 1546 1547 /* ---- Meta block ------------------------------------------------------ */ 1548 .pv-pp-meta { 1549 display: flex; 1550 align-items: center; 1551 gap: 0.625rem; 1552 min-width: 0; 1553 flex: 1 1 auto; 1554 /* Containing block for the mobile expand overlay. Without it the overlay's 1555 `inset: 0` resolved against .pv-pp-bar (which IS positioned), so an 1556 invisible button covered the whole bar and â being the only positioned 1557 sibling â painted over the static play/skip/speed/dismiss buttons. 1558 Every transport tap below 768px opened the sheet instead. */ 1559 position: relative; 1560 } 1561 .pv-pp-art { 1562 width: 40px; 1563 height: 40px; 1564 border-radius: 0.375rem; 1565 object-fit: cover; 1566 flex-shrink: 0; 1567 background: color-mix(in srgb, var(--color-text) 10%, var(--color-background)); 1568 } 1569 .pv-pp-art-fallback { 1570 display: flex; 1571 align-items: center; 1572 justify-content: center; 1573 color: var(--color-primary); 1574 } 1575 .pv-pp-titles { min-width: 0; } 1576 /* min-w-0 + truncate: the title is the ONLY element allowed to give up width. */ 1577 .pv-pp-title { 1578 font-size: 0.8125rem; 1579 font-weight: 600; 1580 line-height: 1.3; 1581 overflow: hidden; 1582 text-overflow: ellipsis; 1583 white-space: nowrap; 1584 color: var(--color-text); 1585 } 1586 .pv-pp-title a { color: inherit; text-decoration: none; } 1587 .pv-pp-title a:hover { color: var(--color-primary); } 1588 .pv-pp-show { 1589 font-size: 0.6875rem; 1590 line-height: 1.3; 1591 overflow: hidden; 1592 text-overflow: ellipsis; 1593 white-space: nowrap; 1594 color: color-mix(in srgb, var(--color-text) 65%, var(--color-background)); 1595 } 1596 1597 /* ---- Transport / scrubber -------------------------------------------- */ 1598 /* The transport NEVER shrinks, at any width. 1599 It used to be `flex: 2 1 0%;
1599 min-width: 0`, which let it collapse to literally 1600 0px whenever the title was long enough to eat the row â and because its 1601 children carry `flex-shrink: 0` (they must, or "1.5x" shatters mid-word) they 1602 kept their 44px and painted OUTSIDE the zero-width box, straight over the 1603 speed, chapters and dismiss buttons that follow it. A long episode title put 1604 "1x" and the dismiss cross on top of the play button. 1605 `.pv-pp-meta` already carries `flex: 1 1 auto; min-width: 0`, so it is the one 1606 that gives way and the title ellipsises â which is the right thing to lose. 1607 The `max-width: 767px` block had this rule all along; it was only ever missing 1608 on desktop. */ 1609 .pv-pp-transport { 1610 display: flex; 1611 align-items: center; 1612 gap: 0.625rem; 1613 flex: 0 0 auto; 1614 } 1615 .pv-pp-scrubwrap { 1616 display: flex; 1617 align-items: center; 1618 gap: 0.5rem; 1619 flex: 1 1 auto; 1620 min-width: 0; 1621 } 1622 .pv-pp-time { 1623 font-variant-numeric: tabular-nums; 1624 font-size: 0.6875rem; 1625 color: color-mix(in srgb, var(--color-text) 65%, var(--color-background)); 1626 } 1627 .pv-pp-live { 1628 font-size: 0.6875rem; 1629 font-weight: 700; 1630 letter-spacing: 0.04em; 1631 color: var(--color-primary); 1632 } 1633 .pv-pp-speed { 1634 font-family: ui-monospace, monospace; 1635 font-size: 0.6875rem; 1636 font-weight: 600; 1637 padding-inline: 0.5rem; 1638 } 1639 .pv-pp-chapter { 1640 font-size: 0.6875rem; 1641 max-width: 14ch; 1642 overflow: hidden; 1643 text-overflow: ellipsis; 1644 color: color-mix(in srgb, var(--color-text) 65%, var(--color-background)); 1645 } 1646 .pv-pp-actions { display: flex; align-items: center; gap: 0.125rem; flex-shrink: 0; } 1647 1648 /* ---- Spinner --------------------------------------------------------- */ 1649 @keyframes pv-pp-spin { to { transform: rotate(360deg); } } 1650 .pv-pp-spinner { 1651 /* A bare <span> is an inline box, and width/height do not apply to one â 1652 the spinner rendered as a 2px sliver of border. It needs a display rule, 1653 which in turn means it needs the [hidden] override below. */ 1654 display: inline-block; 1655 width: 18px; 1656 height: 18px; 1657 border-radius: 9999px; 1658 border: 2px solid color-mix(in srgb, var(--color-background) 55%, transparent); 1659 border-top-color: var(--color-background); 1660 animation: pv-pp-spin 700ms linear infinite; 1661 } 1662 1663 /* The same spinner for a list control (card, featured CTA, hero play link), 1664 which sizes it with the Tailwind box the icon it replaces was using. It 1665 borrows the button's own colour instead of naming a token, because these 1666 controls sit on every surface a theme has: a filled --color-primary disc, 1667 a bare text link, a white overlay on artwork. */ 1668 .pv-card-spinner { 1669 display: inline-block; 1670 border-radius: 9999px; 1671 border: 2px solid color-mix(in srgb, currentColor 30%, transparent); 1672 border-top-color: currentColor; 1673 animation: pv-pp-spin 700ms linear infinite; 1674 } 1675 .pv-card-spinner[hidden] { display: none; } 1676 1677 @media (prefers-reduced-motion: reduce) { 1678 .pv-pp-spinner, .pv-card-spinner { animation-duration: 2.4s; } 1679 } 1680 1681 /* ---- State-driven visibility ---------------------------------------- 1682 Single source of truth: the element's data-state / data-live attributes. 1683 JS only writes the attribute; CSS decides what shows. */ 1684 .pv-pp [data-when] { display: none; } 1685 .pv-pp[data-state="loading"] [data-when~="loading"], 1686 .pv-pp[data-state="playing"] [data-when~="playing"], 1687 .pv-pp[data-state="paused"] [data-when~="paused"], 1688 .pv-pp[data-state="error"] [data-when~="error"], 1689 .pv-pp[data-state="ended"] [data-when~="ended"] { display: inline-flex; } 1690 1691 /* The error message replaces the title block, so it is a block not a flex item. */ 1692 .pv-pp[data-state="error"] [data-when~="error"].pv-pp-errmsg { display: block; } 1693 .pv-pp[data-state="error"] .pv-pp-titles { display: none; } 1694 1695 /* Live / non-finite audio: no meaningful position, so no scrubber, no seek, 1696 no chapters, no speed. */ 1697 .pv-pp[data-live="1"] .pv-pp-scrubwrap, 1698 .pv-pp[data-live="1"] .pv-pp-seek, 1699 .pv-pp[data-live="1"] .pv-pp-chapter, 1700 .pv-pp[data-live="1"] .pv-pp-chapters-btn, 1701 .pv-pp[data-live="1"] .pv-pp-speed { display: none; } 1702 .pv-pp-livebadge { display: none; } 1703 .pv-pp[data-live="1"] .pv-pp-livebadge { display: inline-flex; } 1704 1705 /* Error state disables position controls without hiding the bar. */ 1706 .pv-pp[data-state="error"] .pv-pp-scrubwrap, 1707 .pv-pp[data-state="error"] .pv-pp-seek { display: none; } 1708 1709 /* ---- Narrow-width collapse priority --------------------------------- 1710 Protected at every width: artwork, title, play/pause, scrubber. 1711 Shed in order: chapter label -> speed -> show name -> +-15/30 -> times. */ 1712 @media (max-width: 1023px) { 1713 .pv-pp-chapter { display: none; } 1714 } 1715 @media (max-width: 899px) { 1716 .pv-pp-speed { display: none; } 1717 } 1718 @media (max-width: 767px) { 1719 .pv-pp-show { display: none; } 1720 } 1721 @media (max-width: 639px) { 1722 .pv-pp-seek { display: none; } 1723 } 1724 /* The time labels go at the SAME breakpoint the scrubber leaves the flex row 1725 (767px), not at 479px. Between 480 and 767 the scrubwrap is already the 1726 absolutely-positioned 12px full-bleed strip across the bar's top edge, so the 1727 labels were being laid out inside a 12px sliver at the extreme screen edges â 1728 clipped by the viewport on both sides and painting over the page content above 1729 the bar. Two rules that must move together had drifted apart by 288px. */ 1730 @media (max-width: 767px) { 1731 .pv-pp-time { display: none; } 1732 } 1733 1734 /* Mini-player scrubber. Once the time labels and skips are gone there is not
1735 enough inline room left for a usable track â it collapsed to a ~10px sliver, 1736 which is the one control the collapse priority says must never be lost. So 1737 below the sheet breakpoint it leaves the flex row entirely and becomes a 1738 full-bleed progress line across the top edge of the bar. */ 1739 @media (max-width: 767px) { 1740 .pv-pp:not([data-expanded="1"]) .pv-pp-bar { position: relative; } 1741 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap { 1742 position: absolute; 1743 top: 0; 1744 left: 0; 1745 right: 0; 1746 width: 100%; 1747 gap: 0; 1748 } 1749 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap .public-audio-scrubber { 1750 height: 12px; 1751 margin: 0; 1752 } 1753 /* Shrink the handle so it sits fully inside the bar instead of bulging over 1754 the hairline top border as a stray floating dot. 1755 1756 No negative margin. The strip is the input's own 12px box at `top: 0` of a 1757 bar with `overflow: visible`, so `margin-top: -3px` lifted a 10px handle 1758 three pixels ABOVE the bar and painted it on the page content â the exact 1759 "stray floating dot" the shrink was added to stop. Left to itself the 1760 handle centres in the 12px track, which is what the rule wanted. */ 1761 /* Chrome centres the thumb on the RUNNABLE TRACK, not on the input's box, and 1762 an unstyled track does not inherit the input's 12px â so the thumb centred 1763 on something taller and sat proudly above the bar. Give the track the same 1764 height as the input and the 10px thumb lands in the middle of it. */ 1765 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap .public-audio-scrubber::-webkit-slider-runnable-track { 1766 height: 12px; 1767 } 1768 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap .public-audio-scrubber::-webkit-slider-thumb { 1769 width: 10px; 1770 height: 10px;
1771 margin-top: 1px; /* (12 - 10) / 2 â Chrome needs it stated for a custom thumb */ 1772 } 1773 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap .public-audio-scrubber::-moz-range-track { 1774 height: 12px; 1775 } 1776 .pv-pp:not([data-expanded="1"]) .pv-pp-scrubwrap .public-audio-scrubber::-moz-range-thumb { 1777 width: 10px; 1778 height: 10px; 1779 } 1780 /* Belt and braces: nothing in the mini bar may paint outside it. Scoped to 1781 the collapsed state so the expanded sheet is never clipped. A clip is a 1782 backstop, though â it turns an overflowing handle into a half-moon rather 1783 than fixing it, which is why the geometry above has to be right on its own. */ 1784 .pv-pp:not([data-expanded="1"]) .pv-pp-bar { overflow: hidden; } 1785 } 1786 1787 /* ---- Mobile: mini bar <-> bottom sheet -------------------------------- */ 1788 /* The scrim is a CHILD of .pv-pp, which is itself a stacking context (fixed + 1789 z-index). So these z-indexes are relative to the bar, not the page: the scrim 1790 needs to sit UNDER the bar's own content but still over the whole document, 1791 which it does because the entire subtree paints at the bar's z-index. Giving 1792 it a page-level value (44) made it paint over the sheet it was meant to sit 1793 behind, washing the sheet out. */ 1794 .pv-pp-scrim { 1795 position: fixed; 1796 inset: 0; 1797 /* Stop exactly at the top of the sheet. --pv-player-offset is the bar's own 1798 measured height (ResizeObserver), so it tracks the sheet as it grows â 1799 otherwise the scrim tints the sheet's surface and washes it out. */ 1800 bottom: var(--pv-player-offset, 0px); 1801 z-index: 0; 1802 background: color-mix(in srgb, var(--color-text) 45%, transparent); 1803 display: none; 1804 } 1805 .pv-pp[data-expanded="1"] .pv-pp-scrim { display: block; } 1806 .pv-pp-bar, 1807 .pv-pp-grabber, 1808 .pv-pp-chapters { position: relative; z-index: 1; } 1809 1810 .pv-pp-expand { display: none; } 1811 1812 /* A button carrying .pv-pp-btn cannot be hidden with the `hidden` property â 1813 the author `display: inline-flex` above beats the user-agent [hidden] rule. 1814 These two carry an author display rule, so they get an author hide rule. */ 1815 .pv-pp-btn[data-empty="1"] { display: none; } 1816 .pv-pp-art[hidden], 1817 .pv-pp-spinner[hidden] { display: none; } 1818 1819 @media (max-width: 767px) { 1820 /* The metadata block is the tap target that opens the sheet. */ 1821 .pv-pp-expand { display: block; } 1822 1823 .pv-pp[data-expanded="1"] { 1824 border-top-left-radius: 1rem; 1825 border-top-right-radius: 1rem; 1826 /* A short lift, NOT pv-pp-rise: the bar is already on screen, so 1827 re-running a translateY(100%) slide drops the sheet's lower half 1828 below the fold for the length of the animation. */ 1829 animation: pv-pp-sheet 200ms ease-out both; 1830 } 1831 /* Sheet layout: the SAME controls reflow into a taller stack â no second 1832 copy of the transport to drift out of sync. */ 1833 .pv-pp[data-expanded="1"] .pv-pp-bar { 1834 flex-direction: column; 1835 align-items: stretch; 1836 gap: 0.875rem; 1837 padding: 0.5rem 1.25rem 1.25rem; 1838 } 1839 .pv-pp[data-expanded="1"] .pv-pp-grabber { display: block; } 1840 .pv-pp[data-expanded="1"] .pv-pp-art { width: 96px; height: 96px; } 1841 .pv-pp[data-expanded="1"] .pv-pp-meta { flex-direction: column; text-align: center; gap: 0.75rem; } 1842 .pv-pp[data-expanded="1"] .pv-pp-title { white-space: normal; } 1843 /* Everything the narrow-width rules shed comes back inside the sheet. */ 1844 .pv-pp[data-expanded="1"] .pv-pp-show, 1845 .pv-pp[data-expanded="1"] .pv-pp-time, 1846 .pv-pp[data-expanded="1"] .pv-pp-speed, 1847 .pv-pp[data-expanded="1"] .pv-pp-chapter { display: block; } 1848 .pv-pp[data-expanded="1"] .pv-pp-seek { display: inline-flex; } 1849 .pv-pp[data-expanded="1"] .pv-pp-transport { flex-direction: column; gap: 0.75rem; } 1850 .pv-pp[data-expanded="1"] .pv-pp-scrubwrap { width: 100%; } 1851 .pv-pp[data-expanded="1"] .pv-pp-controls { justify-content: center; gap: 0.75rem; } 1852 } 1853 1854 .pv-pp-grabber { 1855 display: none; 1856 width: 36px; 1857 height: 4px; 1858 border-radius: 9999px; 1859 margin: 0.5rem auto 0; 1860 background: color-mix(in srgb, var(--color-text) 25%, var(--color-background)); 1861 } 1862 1863 /* ---- Reduced motion -------------------------------------------------- 1864 Instant appear. No slide, no spin. */ 1865 @media (prefers-reduced-motion: reduce) { 1866 .pv-pp[data-animate="in"], 1867 .pv-pp[data-expanded="1"] { animation: none; transform: none; opacity: 1; } 1868 .pv-pp-spinner { animation: none; } 1869 } 1870</style> 1871 1872<pv-persistent-player id="pv-persistent-player" 1873 class="pv-pp" 1874 data-state="idle" 1875 data-expanded="0" 1876 style="display:none" 1877 role="region" 1878 1879 data-label-play="Play" 1880 data-label-pause="Pause" 1881 data-label-replay="Replay" 1882 data-label-retry="Retry" 1883 aria-label="Audio player"> 1884 1885 1886 <audio id="pv-persistent-audio" data-primary-audio data-role="audio" preload="metadata"></audio> 1887 1888 1889 <div class="pv-pp-scrim" data-role="scrim" aria-hidden="true"></div> 1890 1891 <div class="pv-pp-grabber" data-role="grabber" aria-hidden="true"></div> 1892 1893 <div class="pv-pp-bar"> 1894 1895 1896 <div class="pv-pp-meta"> 1897 <img class="pv-pp-art" data-role="artwork" src="" alt="" hidden> 1898 <div class="pv-pp-art pv-pp-art-fallback" data-role="artwork-fallback"> 1899 <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1900 <path stroke-linecap="round" stroke-linejoin="round" d="m9 9 10.5-3m0 6.553v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 1 1-.99-3.467l2.31-.66a2.25 2.25 0 0 0 1.632-2.163Zm0 0V2.25L9 5.25v10.303m0 0v3.75a2.25 2.25 0 0 1-1.632 2.163l-1.32.377a1.803 1.803 0 0 1-.99-3.467l2.31-.66A2.25 2.25 0 0 0 9 15.553Z" /> 1901</svg> 1902 </div> 1903 1904 <div class="pv-pp-titles" data-role="titles"> 1905 1906 <div class="pv-pp-title" data-role="title"> 1907 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="#" data-role="permalink"></a> 1908 </div> 1909 <div class="pv-pp-show" data-role="show"></div> 1910 </div> 1911 1912 1913 <div class="pv-pp-errmsg" data-when="error" role="alert"> 1914 <div class="pv-pp-title">Couldn't play this episode</div> 1915 </div> 1916 1917 1918 <button type="button" 1919 class="pv-pp-expand" 1920 data-role="expand" 1921 aria-expanded="false" 1922 aria-label="Show player details" 1923 style="position:absolute;inset:0;width:100%;height:100%;opacity:0"></button> 1924 </div> 1925 1926 1927 <div class="pv-pp-transport"> 1928 <div class="pv-pp-controls" style="display:flex;align-items:center;gap:0.125rem"> 1929 <button type="button" class="pv-pp-btn pv-pp-seek" data-role="skip-back" 1930 aria-label="Skip back 15 seconds" title="â15s"> 1931 1932<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"> 1933 <path d="M11.7331 5.02519C11.3312 5.12558 10.9241 4.88118 10.8237 4.47932C10.7233 4.07746 10.9677 3.6703 11.3696 3.56991L11.7331 5.02519ZM17.1313 4.29303L17.3119 3.5651L17.3127 3.5653L17.1313 4.29303ZM22.7001 7.66158L23.2605 7.16308L23.2614 7.16415L22.7001 7.66158ZM25.3454 13.5545L26.0902 13.4656L26.0903 13.4664L25.3454 13.5545ZM24.1853 19.9886L24.8525 20.3312L24.8525 20.3312L24.1853 19.9886ZM10.9484 26.0337L11.1259 25.305L11.1264 25.3051L10.9484 26.0337ZM2.69045 14.5853L1.94297 14.5238L1.94299 14.5236L2.69045 14.5853ZM4.51243 7.99796C4.76893 7.67272 5.24053 7.617 5.56576 7.87351C5.891 8.13001 5.94671 8.60161 5.69021 8.92684L4.51243 7.99796ZM12.0777 4.83186C11.7826 5.12254 11.3077 5.11896 11.017 4.82387C10.7263 4.52877 10.7299 4.05391 11.025 3.76324L12.0777 4.83186ZM14.3208 0.516822C14.6159 0.226146 15.0907 0.229727 15.3814 0.52482C15.6721 0.819914 15.6685 1.29477 15.3734 1.58545L14.3208 0.516822ZM11.0252 4.832C10.73 4.5414 10.7263 4.06654 11.0169 3.77137C11.3075 3.4762 11.7823 3.4725 12.0775 3.7631L11.0252 4.832ZM15.2871 6.92302C15.5823 7.21362 15.586 7.68847 15.2954 7.98364C15.0048 8.27881 14.53 8.28252 14.2348 7.99192L15.2871 6.92302ZM11.3696 3.56991C13.3202 3.08262 15.3605 3.08097 17.3119 3.5651L16.9507 5.02096C15.2373 4.59588 13.4458 4.59733 11.7331 5.02519L11.3696 3.56991ZM17.3127 3.5653C19.6123 4.13849 21.6853 5.39244 23.2605 7.16308L22.1398 8.16009C20.7653 6.61508 18.9565 5.52092 16.9499 5.02076L17.3127 3.5653ZM23.2614 7.16415C24.8242 8.9275 25.8111 11.1261 26.0902 13.4656L24.6007 13.6433C24.3578 11.6071 23.4989 9.69369 22.1388 8.15902L23.2614 7.16415ZM26.0903 13.4664C26.3692 15.8268 25.9383 18.2169 24.8525 20.3312L23.5181 19.6459C24.4677 17.7969 24.8446 15.7068 24.6006 13.6425L26.0903 13.4664ZM24.8525 20.3312C22.2111 25.4741 16.387 28.1339 10.7705 26.7623L11.1264 25.3051C16.0687 26.5121 21.1938 24.1715 23.5182 19.6459L24.8525 20.3312ZM10.771 26.7624C5.21828 25.41 1.47425 20.2196 1.94297 14.5238L3.43792 14.6469C3.02973 19.6071 6.29027 24.1273 11.1259 25.305L10.771 26.7624ZM1.94299 14.5236C2.1396 12.1432 3.0333 9.87342 4.51243 7.99796L5.69021 8.92684C4.39364 10.5
1933708 3.61024 12.5604 3.4379 14.6471L1.94299 14.5236ZM11.025 3.76324L14.3208 0.516822L15.3734 1.58545L12.0777 4.83186L11.025 3.76324ZM12.0775 3.7631L15.2871 6.92302L14.2348 7.99192L11.0252 4.832L12.0775 3.7631Z" fill="currentColor"/> 1934 <path d="M10.9275 18.7299V13.253H10.8507L9.21032 14.4234V13.4292L10.9275 12.2091H11.9398V18.7299H10.9275ZM15.8624 18.8881C14.579 18.8881 13.6933 18.0882 13.6029 17.0308L13.5984 16.9721H14.5474L14.5519 17.0082C14.6378 17.5821 15.1575 18.0385 15.8714 18.0385C16.6758 18.0385 17.2362 17.4646 17.2362 16.6467V16.6377C17.2362 15.8333 16.6668 15.2639 15.8805 15.2639C15.4828 15.2639 15.1439 15.3814 14.8863 15.6164C14.7688 15.7203 14.6649 15.8468 14.5881 15.996H13.7159L14.0413 12.2091H17.8327V13.0677H14.8366L14.6378 15.1464H14.7146C14.9903 14.7081 15.5009 14.455 16.1019 14.455C17.3266 14.455 18.2032 15.3678 18.2032 16.6196V16.6286C18.2032 17.9662 17.2362 18.8881 15.8624 18.8881Z" fill="currentColor"/> 1935</svg> 1936 1937 </button> 1938 1939 <button type="button" class="pv-pp-btn pv-pp-play" data-role="play" 1940 aria-label="Play"> 1941 <span data-role="play-icon"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1942 <path fill-rule="evenodd" d="M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z" clip-rule="evenodd" /> 1943</svg></span> 1944 <span data-role="pause-icon" hidden><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1945 <path fill-rule="evenodd" d="M6.75 5.25a.75.75 0 0 1 .75-.75H9a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H7.5a.75.75 0 0 1-.75-.75V5.25Zm7.5 0A.75.75 0 0 1 15 4.5h1.5a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H15a.75.75 0 0 1-.75-.75V5.25Z" clip-rule="evenodd" /> 1946</svg></span> 1947 1948 <span data-role="replay-icon" hidden><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1949 <path fill-rule="evenodd" d="M4.755 10.059a7.5 7.5 0 0 1 12.548-3.364l1.903 1.903h-3.183a.75.75 0 1 0 0 1.5h4.992a.75.75 0 0 0 .75-.75V4.356a.75.75 0 0 0-1.5 0v3.18l-1.9-1.9A9 9 0 0 0 3.306 9.67a.75.75 0 1 0 1.45.388Zm15.408 3.352a.75.75 0 0 0-.919.53 7.5 7.5 0 0 1-12.548 3.364l-1.902-1.903h3.183a.75.75 0 0 0 0-1.5H2.984a.75.75 0 0 0-.75.75v4.992a.75.75 0 0 0 1.5 0v-3.18l1.9 1.9a9 9 0 0 0 15.059-4.035.75.75 0 0 0-.53-.918Z" clip-rule="evenodd" /> 1950</svg></span> 1951 1952 <span data-role="retry-icon" hidden><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1953 <path fill-rule="evenodd" d="M4.755 10.059a7.5 7.5 0 0 1 12.548-3.364l1.903 1.903h-3.183a.75.75 0 1 0 0 1.5h4.992a.75.75 0 0 0 .75-.75V4.356a.75.75 0 0 0-1.5 0v3.18l-1.9-1.9A9 9 0 0 0 3.306 9.67a.75.75 0 1 0 1.45.388Zm15.408 3.352a.75.75 0 0 0-.919.53 7.5 7.5 0 0 1-12.548 3.364l-1.902-1.903h3.183a.75.75 0 0 0 0-1.5H2.984a.75.75 0 0 0-.75.75v4.992a.75.75 0 0 0 1.5 0v-3.18l1.9 1.9a9 9 0 0 0 15.059-4.035.75.75 0 0 0-.53-.918Z" clip-rule="evenodd" /> 1954</svg></span> 1955 <span class="pv-pp-spinner" data-role="spinner" hidden></span> 1956 </button> 1957 1958 <button type="button" class="pv-pp-btn pv-pp-seek" data-role="skip-fwd" 1959 aria-label="Skip forward 30 seconds" title="+30s"> 1960 1961<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"> 1962 <path d="M15.9968 5.02519C16.3987 5.12558 16.8058 4.88118 16.9062 4.47932C17.0066 4.07746 16.7622 3.6703 16.3604 3.56991L15.9968 5.02519ZM10.5986 4.29303L10.418 3.5651L10.4172 3.5653L10.5986 4.29303ZM5.02978 7.66158L4.46943 7.16308L4.46848 7.16415L5.02978 7.66158ZM2.38449 13.5545L1.63977 13.4656L1.63968 13.4664L2.38449 13.5545ZM3.54462 19.9886L2.87746 20.3312L2.87747 20.3312L3.54462 19.9886ZM16.7815 26.0337L16.604 25.305L16.6036 25.3051L16.7815 26.0337ZM25.0395 14.5853L25.787 14.5238L25.7869 14.5236L25.0395 14.5853ZM23.2175 7.99796C22.961 7.67272 22.4894 7.617 22.1642 7.87351C21.8389 8.13001 21.7832 8.60161 22.0397 8.92684L23.2175 7.99796ZM15.6523 4.83186C15.9474 5.12254 16.4222 5.11896 16.7129 4.82387C17.0036 4.52877 17 4.05391 16.7049 3.76324L15.6523 4.83186ZM13.4092 0.516822C13.1141 0.226146 12.6392 0.229727 12.3485 0.52482C12.0579 0.819914 12.0614 1.29477 12.3565 1.58545L13.4092 0.516822ZM16.7048 4.832C16.9999 4.5414 17.0036 4.06654 16.713 3.77137C16.4224 3.4762 15.9476 3.4725 15.6524 3.7631L16.7048 4.832ZM12.4428 6.92302C12.1476 7.21361 12.1439 7.68847 12.4345 7.98364C12.7251 8.27881 13.2 8.28252 13.4951 7.99192L12.4428 6.92302ZM16.3604 3.56991C14.4097 3.08262 12.3694 3.08097 10.418 3.5651L10.7792 5.02096C12.4926 4.59588 14.2841 4.59733 15.9968 5.02519L16.3604 3.56991ZM10.4172 3.5653C8.11764 4.13849 6.04465 5.39244 4.46943 7.16308L5.59013 8.16009C6.96463 6.61508 8.77346 5.52092 10.78 5.02076L10.4172 3.5653ZM4.46848 7.16415C2.90577 8.9275 1.91885 11.1261 1.63977 13.4656L3.12921 13.6433C3.3721 11.6071 4.23103 9.69369 5.59108 8.15902L4.46848 7.16415ZM1.63968 13.4664C1.36068 15.8268 1.79163 18.2169 2.87746 20.3312L4.21178 19.6459C3.26219 17.7969 2.88532 15.7068 3.12931 13.6425L1.63968 13.4664ZM2.87747 20.3312C5.51882 25.4741 11.343 28.1339 16.9594 26.7623L16.6036 25.3051C11.6612 26.5121 6.5361 24.1715 4.21178 19.6459L2.87747 20.3312ZM16.959 26.7624C22.5116 25.41 26.2557 20.2196 25.787 14.5238L24.292 14.6469C24.7002 19.6071 21.4397 24.1273 16.604 25.305L16.959 26.7624ZM25.7869 14.5236C25.5903 12.1432 24.6966 9.87342 23.2175 7.99796L22.0397 8.92684C23.3363 10.5708 24.1197 12.5604 24.292 14.6471L25.7869 14.5236ZM16.7049 3.76324L13.4092 0.516822L12.3565 1.58545L15.6523 4.83186L16.7049 3.76324ZM15.6524 3.7631L12.4428 6.92302L13.4951 7.99192L16.7048 4.832L15.6524 3.7631Z" fill="currentColor"/> 1963 <path d="M10.9701 18.8519C9.57822 18.8519 8.66991 18.0882 8.58405 17.0082L8.57953 16.954H9.54658L9.5511 16.9992C9.61437 17.5912 10.1612 18.0069 10.9701 18.0069C11.7654 18.0069 12.3032 17.5595 12.3032 16.9178V16.9088C12.3032 16.1722 11.7699 15.761 10.9023 15.761H10.1069V14.9747H10.8706C11.6163 14.9747 12.1224 14.5363 12.1224 13.9308V13.9218C12.1224 13.2891 11.6976 12.9186 10.961 12.9186C10.238 12.9186 9.73186 13.3027 9.6686 13.9172L9.66408 13.9624H8.7151L8.71961 13.9127C8.81903 12.8146 9.68667 12.0871 10.961 12.0871C12.258 12.0871 13.1075 12.783 13.1075 13.7907V13.7997C13.1075 14.6086 12.5291 15.1509 11.7338 15.3181V15.3407C12.6918 15.4266 13.3335 16.005 13.3335 16.9178V16.9269C13.3335 18.0476 12.3529 18.8519 10.9701 18.8519ZM16.7184 18.8881C1
19635.2135 18.8881 14.3097 17.5731 14.3097 15.4718V15.4627C14.3097 13.3614 15.2135 12.0509 16.7184 12.0509C18.2187 12.0509 19.127 13.3614 19.127 15.4627V15.4718C19.127 17.5731 18.2187 18.8881 16.7184 18.8881ZM16.7184 18.0476C17.5905 18.0476 18.1057 17.067 18.1057 15.4718V15.4627C18.1057 13.8675 17.5905 12.896 16.7184 12.896C15.8417 12.896 15.331 13.8675 15.331 15.4627V15.4718C15.331 17.067 15.8417 18.0476 16.7184 18.0476Z" fill="currentColor"/> 1964</svg> 1965 1966 </button> 1967 </div> 1968 1969 <div class="pv-pp-scrubwrap"> 1970 <span class="pv-pp-time" data-role="time-current">0:00</span> 1971 <input type="range" 1972 class="public-audio-scrubber" 1973 style="flex:1 1 auto;min-width:0;background:transparent;appearance:none;cursor:pointer" 1974 data-role="scrubber" 1975 value="0" min="0" max="100" step="0.1" 1976 aria-label="Seek"> 1977 <span class="pv-pp-time" data-role="time-total">--:--</span> 1978 </div> 1979 1980 <span class="pv-pp-live pv-pp-livebadge">LIVE</span> 1981 </div> 1982 1983 1984 <div class="pv-pp-actions"> 1985 <span class="pv-pp-chapter" data-role="current-chapter"></span> 1986 1987 <button type="button" class="pv-pp-btn pv-pp-speed" data-role="speed" 1988 aria-label="Playback speed" 1989 title="Playback speed">1Ã</button> 1990 1991 1992 <button type="button" class="pv-pp-btn pv-pp-chapters-btn" data-role="chapters-toggle" 1993 aria-expanded="false" data-empty="1" 1994 aria-label="Chapters" 1995 title="Chapters"> 1996 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 1997 <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25H12" /> 1998</svg> 1999 </button> 2000 2001 2002 <button type="button" class="pv-pp-btn" data-role="dismiss" 2003 aria-label="Close player" 2004 title="Close player"> 2005 <svg fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true" width="24" height="24" class="w-5 h-5"> 2006 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> 2007</svg> 2008 </button> 2009 </div> 2010 </div> 2011 2012 2013 <div class="pv-pp-chapters" data-role="chapters-panel" hidden 2014 style="max-height:16rem;overflow-y:auto;padding:0.5rem 1rem 1rem; 2015 border-top:1px solid color-mix(in srgb, var(--color-text) 12%, var(--color-background))"></div> 2016</pv-persistent-player> 2017 2018 2019 2020 <p class="sr-only" aria-live="polite" data-pv-route-announce></p> 2021 2022
2022<script src="/static/js/transcript-toggle.2caf56525409.js"></script>
2022 2023
2023<script src="/static/js/pv-boost-nav.2f011fe57dd9.js" defer></script>
2023 2024
2024<script src="/static/js/chapter_seek.df6e32ab809f.js" defer></script>
2024 2025
2025<script src="/static/js/chaptered_player.20b62baf4764.js" defer></script>
2025 2026
2026<script src="/static/js/hls-player.7e1cd4eb69de.js" defer></script>
2026 2027
2027<script src="/static/js/episode_tabs.a0e8bc4376fd.js" defer></script>
2027 2028
2028<script src="/static/js/host-player.a243d8a07ae2.js" defer></script>
2028 2029
2029<script src="/static/js/pv-hero-motion.2f219bb77669.js" defer></script>
2029 2030 2031 <!-- email-signup-guard-hydrator:start --> 2032 <template id="email-signup-bot-fields-template"> 2033 2034<!-- email-signup-bot-fields:start --> 2035<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;"> 2036 <label> 2037 Website 2038 <input type="text" 2039 name="website" 2040 value="" 2041 tabindex="-1" 2042 autocomplete="off"> 2043 </label> 2044</div> 2045<input type="hidden" name="signup_timing_token" value="eyJpc3N1ZWRfYXQiOjE3OTA5MTcxOTcuMjg4NzAyNX0:1xCVNF:q3WMHk43GGMopDaZY4kz3BWRl0nIDe0piDzwGt5Cods"> 2046 2047<input type="hidden" name="cf-turnstile-response" value=""> 2048 2049<iframe class="email-signup-turnstile-frame" 2050 data-src="https://podview.com/_turnstile/email-signup/?embed=Imh0dHBzOi8vd3d3LmNvZGVzdG9yeS5jbyI%3A1xCVNF%3A15wmHC8bGy9KX9Dzpv3TIMeFLt5t1Ne8wulgP7JjYpc" 2051 title="Security verification" 2052 scrolling="no" 2053 style="position:absolute;width:1px;height:1px;border:0;clip-path:inset(50%);overflow:hidden;"></iframe> 2054 2055<p class="email-signup-challenge-error w-full text-xs text-theme-text-muted" role="alert" hidden>Verification couldn't load. Please refresh and try again.</p> 2056 2057<!-- email-signup-bot-fields:end --> 2058 2059 </template> 2060
2060<script src="/static/js/email-signup-guards.2dfe65de62dc.js"></script>
2060 2061 <!-- email-signup-guard-hydrator:end --> 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074<div id="pw-cookie-banner" 2075 class="fixed bottom-0 left-0 right-0 z-50 p-4 transform transition-transform duration-300" 2076 2077 style="display: none; margin-bottom: var(--pv-player-offset, 0px);"> 2078 <div class="max-w-4xl mx-auto bg-white/95 backdrop-blur-sm border border-gray-200 rounded-lg shadow-lg p-4 sm:p-6"> 2079 <div class="flex flex-col sm:flex-row sm:items-center gap-4"> 2080 <div class="flex-1"> 2081 <p class="text-sm text-gray-700"> 2082 We use cookies to analyze site traffic and improve your experience. 2083 <a hx-boost="true" hx-target="#pv-public-content" hx-select="#pv-public-content" hx-swap="outerHTML show:window:top" hx-push-url="true" href="/privacy/" class="text-blue-600 hover:underline">Learn more</a> 2084 </p> 2085 </div> 2086 <div class="flex items-center gap-3 flex-shrink-0"> 2087 <button onclick="pwRejectCookies()" 2088 class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition"> 2089 Reject 2090 </button> 2091 <button onclick="pwAcceptCookies()" 2092 class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition"> 2093 Accept 2094 </button> 2095 </div> 2096 </div> 2097 </div> 2098</div> 2099 2100
2101<script> 2102(function() { 2103 // Cookie consent management 2104 const CONSENT_COOKIE = 'pw_analytics_consent'; 2105 const CONSENT_DURATION = 365; // days 2106 2107 function getConsent() { 2108 const cookies = document.cookie.split('; '); 2109 for (const cookie of cookies) { 2110 const [name, value] = cookie.split('='); 2111 if (name === CONSENT_COOKIE) return value; 2112 } 2113 return null; 2114 } 2115 2116 function setConsent(value) { 2117 const date = new Date(); 2118 date.setTime(date.getTime() + (CONSENT_DURATION * 24 * 60 * 60 * 1000)); 2119 document.cookie = CONSENT_COOKIE + '=' + value + ';expires=' + date.toUTCString() + ';path=/;SameSite=Lax'; 2120 } 2121 2122 function hideBanner() { 2123 const banner = document.getElementById('pw-cookie-banner'); 2124 if (banner) banner.style.display = 'none'; 2125 } 2126 2127 function showBanner() { 2128 const banner = document.getElementById('pw-cookie-banner'); 2129 if (banner) banner.style.display = 'block'; 2130 } 2131 2132 function loadTrackingScripts() { 2133 2134 // Load Google Analytics 4 2135 (function() { 2136 var s = document.createElement('script'); 2137 s.async = true; 2138 s.src = 'https://www.googletagmanager.com/gtag/js?id=G\u002DV7FRJ8V1EH'; 2139 document.head.appendChild(s); 2140 2141 window.dataLayer = window.dataLayer || []; 2142 function gtag(){dataLayer.push(arguments);} 2143 gtag('js', new Date()); 2144 gtag('config', 'G\u002DV7FRJ8V1EH'); 2145 })(); 2146 2147 2148 2149 } 2150 2151 // Global functions for button handlers 2152 window.pwAcceptCookies = function() { 2153 setConsent('accepted'); 2154 hideBanner(); 2155 loadTrackingScripts(); 2156 }; 2157 2158 window.pwRejectCookies = function() { 2159 setConsent('rejected'); 2160 hideBanner(); 2161 }; 2162 2163 // Initialize on page load 2164 2165 // GDPR mode: check consent before loading scripts 2166 var consent = getConsent(); 2167 if (consent === 'accepted') { 2168 loadTrackingScripts(); 2169 } else if (consent === 'rejected') { 2170 // Do nothing, user rejected 2171 } else { 2172 // No consent yet, show banner 2173 showBanner(); 2174 } 2175 2176})(); 2177</script>
2177 2178 2179 2180 2181 2182 2183 2184 2185
2186<script src="/static/js/play-beacon.858142c57b9f.js" defer></script>
2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196
2197<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a44124027d25e802',t:'MTc5MDkxNzE5Nw=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
2197<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"512eef4f250244daad5aa4c2fdbacceb","r":1,"spa":2}' crossorigin="anonymous"></script>
2197 2198</body> 2199</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.