Skip to content

Commit 3bbc5b6

Browse files
committed
feat(site,courses): implement YouTube 100K conversion funnel, 4 new 2026 courses, and portal guest launch pack
1 parent d364ec0 commit 3bbc5b6

7 files changed

Lines changed: 1107 additions & 12 deletions

File tree

‎apps/site/src/components/AnimatedHero.astro‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,32 @@ import AjAnimatedMascot from "@/components/AjAnimatedMascot.astro";
9090
<span>Read Blog</span>
9191
</a>
9292
</div>
93+
94+
{/* Road to 100K YouTube Subscribers Progress Pill */}
95+
<a
96+
href="https://www.youtube.com/@codingcatdev?sub_confirmation=1"
97+
target="_blank"
98+
rel="noopener noreferrer"
99+
class="group mt-1 flex w-full max-w-md flex-col gap-2 rounded-2xl border-2 border-[#2A1155] bg-white p-3.5 shadow-sketch-sm transition hover:-translate-y-0.5 hover:border-[#FF0000] dark:border-white/25 dark:bg-[#131B2E]"
100+
>
101+
<div class="flex items-center justify-between gap-2 text-xs">
102+
<span class="flex items-center gap-2 font-display font-black text-[#2A1155] group-hover:text-[#DC2626] dark:text-white dark:group-hover:text-red-400">
103+
<span class="inline-flex size-5 items-center justify-center rounded-full bg-[#FF0000] text-[10px] text-white">
104+
▶
105+
</span>
106+
<span>@CodingCatDev YouTube</span>
107+
</span>
108+
<span class="font-mono font-extrabold text-[#7C3AED] dark:text-[#C084FC]">
109+
62.5K / 100K Subs →
110+
</span>
111+
</div>
112+
<div class="h-2.5 w-full overflow-hidden rounded-full border border-[#2A1155]/30 bg-[#EDE9FE] dark:border-white/20 dark:bg-[#0B1326]">
113+
<div
114+
class="h-full rounded-full bg-gradient-to-r from-[#7C3AED] via-[#A855F7] to-[#FF0000]"
115+
style="width: 62.5%"
116+
></div>
117+
</div>
118+
</a>
93119
</div>
94120

95121
{/* Mini Stats Row */}

‎apps/site/src/components/portable-text/PtYouTube.astro‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,53 @@ const alt = rawAlt && rawAlt.trim().length > 0 ? rawAlt : "";
8383
</svg>
8484
</button>
8585
</div>
86+
87+
{/* High-Conversion CodingCat.dev YouTube Subscribe & Continuous Playlist Action Bar */}
88+
<div class="mt-3 flex flex-wrap items-center justify-between gap-3 rounded-2xl border-2 border-[#2A1155] bg-[#FAF9FC] px-4 py-3 shadow-sketch-sm dark:border-white/25 dark:bg-[#131B2E]">
89+
<div class="flex flex-wrap items-center gap-3">
90+
<a
91+
href="https://www.youtube.com/@codingcatdev?sub_confirmation=1"
92+
target="_blank"
93+
rel="noopener noreferrer"
94+
class="flex items-center gap-2.5 group"
95+
>
96+
<span class="inline-flex size-9 shrink-0 items-center justify-center rounded-full border-2 border-[#2A1155] bg-[#FF0000] text-white shadow-sketch-sm dark:border-white/60">
97+
<svg class="size-4 fill-current" viewBox="0 0 24 24" aria-hidden="true">
98+
<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" />
99+
</svg>
100+
</span>
101+
<span class="flex flex-col">
102+
<span class="font-display text-sm font-black leading-tight text-[#2A1155] group-hover:text-[#7C3AED] dark:text-white dark:group-hover:text-[#C084FC]">
103+
@CodingCatDev
104+
</span>
105+
<span class="font-mono text-[11px] font-bold text-[#2A1155]/75 dark:text-slate-300">
106+
62.5K / 100K Subscribers Goal
107+
</span>
108+
</span>
109+
</a>
110+
111+
<a
112+
href="https://www.youtube.com/@codingcatdev?sub_confirmation=1"
113+
target="_blank"
114+
rel="noopener noreferrer"
115+
class="tactile-btn inline-flex items-center gap-1.5 rounded-xl border-2 border-[#2A1155] bg-[#FF0000] px-3.5 py-1.5 font-display text-xs font-black text-white shadow-sketch-sm transition hover:bg-[#DC2626] dark:border-white/70"
116+
>
117+
<span>Subscribe on YouTube</span>
118+
<span>→</span>
119+
</a>
120+
</div>
121+
122+
<div class="flex flex-wrap items-center gap-2">
123+
<a
124+
href={`https://www.youtube.com/watch?v=${id}&list=UUnKZ8gEb78zXKMi1ns-IQ2g`}
125+
target="_blank"
126+
rel="noopener noreferrer"
127+
class="inline-flex items-center gap-1.5 rounded-xl border-2 border-[#2A1155] bg-white px-3.5 py-1.5 font-mono text-xs font-extrabold text-[#2A1155] shadow-sketch-sm transition hover:border-[#7C3AED] hover:bg-[#EDE9FE] hover:text-[#7C3AED] dark:border-white/25 dark:bg-[#0B1326] dark:text-white dark:hover:border-[#C084FC] dark:hover:bg-purple-950/60"
128+
>
129+
<span>Watch on YouTube App ↗</span>
130+
</a>
131+
</div>
132+
</div>
86133
</div>
87134
)
88135
}

‎apps/site/src/pages/course/[slug].astro‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,30 @@ const sanitizedContent = (course.content ?? []).filter((block) => {
9696
)
9797
}
9898
</div>
99-
{
100-
firstLesson?.slug && (
101-
<a
102-
href={`/course/${slug}/lesson/${firstLesson.slug}`}
103-
class="tactile-btn inline-flex items-center gap-2 rounded-xl border-2 border-[#2A1155] bg-[#7C3AED] px-5 py-2.5 font-display text-sm font-black text-white shadow-sketch-sm transition hover:bg-[#6D28D9] dark:border-white/80"
104-
>
105-
Start Course →
106-
</a>
107-
)
108-
}
99+
<div class="flex flex-wrap items-center gap-2.5">
100+
<a
101+
href={
102+
course.youtube ||
103+
firstLesson?.youtube ||
104+
"https://www.youtube.com/@codingcatdev/playlists?sub_confirmation=1"
105+
}
106+
target="_blank"
107+
rel="noopener noreferrer"
108+
class="inline-flex items-center gap-2 rounded-xl border-2 border-[#2A1155] bg-white px-4 py-2.5 font-display text-xs font-black text-[#2A1155] shadow-sketch-sm transition hover:border-[#FF0000] hover:bg-[#FEF2F2] hover:text-[#DC2626] dark:border-white/25 dark:bg-[#131B2E] dark:text-white dark:hover:border-red-400"
109+
>
110+
<span>▶ Watch Course Playlist on YouTube ↗</span>
111+
</a>
112+
{
113+
firstLesson?.slug && (
114+
<a
115+
href={`/course/${slug}/lesson/${firstLesson.slug}`}
116+
class="tactile-btn inline-flex items-center gap-2 rounded-xl border-2 border-[#2A1155] bg-[#7C3AED] px-5 py-2.5 font-display text-sm font-black text-white shadow-sketch-sm transition hover:bg-[#6D28D9] dark:border-white/80"
117+
>
118+
Start Course →
119+
</a>
120+
)
121+
}
122+
</div>
109123
</div>
110124

111125
<h1 class="mb-8 break-words font-display text-3xl font-black leading-tight tracking-tight text-[#2A1155] dark:text-white sm:text-4xl md:text-6xl">

‎apps/site/src/pages/course/[slug]/lesson/[lessonSlug].astro‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,28 @@ const lessonDescription = currentLesson.excerpt || course.excerpt || "";
339339
))
340340
}
341341
</div>
342+
343+
<div class="mt-5 rounded-2xl border-2 border-[#2A1155] bg-[#FAF9FC] p-3.5 shadow-sketch-sm dark:border-white/25 dark:bg-[#0B1326]">
344+
<div class="flex items-center justify-between gap-2">
345+
<span class="font-display text-xs font-black text-[#2A1155] dark:text-white">
346+
@CodingCatDev on YouTube
347+
</span>
348+
<span class="font-mono text-[10px] font-extrabold text-[#7C3AED] dark:text-[#C084FC]">
349+
62.5K / 100K
350+
</span>
351+
</div>
352+
<p class="mt-1 text-[11px] font-medium text-[#2A1155]/75 dark:text-slate-300">
353+
Subscribe for new course lessons and architecture deep dives every week.
354+
</p>
355+
<a
356+
href="https://www.youtube.com/@codingcatdev?sub_confirmation=1"
357+
target="_blank"
358+
rel="noopener noreferrer"
359+
class="tactile-btn mt-2.5 flex w-full items-center justify-center gap-1.5 rounded-xl border-2 border-[#2A1155] bg-[#FF0000] px-3 py-2 font-display text-xs font-black text-white shadow-sketch-sm transition hover:bg-[#DC2626] dark:border-white/70"
360+
>
361+
<span>Subscribe for New Lessons →</span>
362+
</a>
363+
</div>
342364
</aside>
343365
</div>
344366
</article>

‎apps/site/src/pages/portal/[token].astro‎

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,12 +1351,60 @@ const pageDescription = !portalFound
13511351
</form>
13521352
</section>
13531353

1354+
<!-- 1-Click Guest Co-Distribution Launch Pack -->
1355+
<section
1356+
id="launch-pack"
1357+
class="flex flex-col gap-4 p-6 rounded-2xl border-2 border-primary/30 bg-card shadow-xs scroll-mt-24"
1358+
>
1359+
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-border pb-3">
1360+
<div class="flex flex-col gap-1">
1361+
<span class="text-xs font-mono uppercase tracking-wider text-primary font-bold">
1362+
🚀 1-Click Guest Co-Distribution Launch Pack (@CodingCatDev YouTube)
1363+
</span>
1364+
<h2 class="text-lg font-bold tracking-tight text-foreground">
1365+
Pre-Written Social Thread (Zero-Link Main Post + YouTube Reply #1)
1366+
</h2>
1367+
<p class="text-xs text-muted-foreground">
1368+
X and LinkedIn suppress reach by 50% to 80% when a link is in the main post. Copy the Main Post with our dark-mode architecture diagram or native clip, then drop Reply #1 immediately underneath.
1369+
</p>
1370+
</div>
1371+
<a
1372+
href="https://www.youtube.com/@codingcatdev?sub_confirmation=1"
1373+
target="_blank"
1374+
rel="noopener noreferrer"
1375+
class="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-lg bg-[#FF0000] text-white font-semibold text-xs hover:opacity-90 transition-opacity shrink-0"
1376+
>
1377+
Subscribe to @CodingCatDev (62.5K / 100K) ↗
1378+
</a>
1379+
</div>
1380+
1381+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
1382+
<div class="flex flex-col gap-2 p-4 rounded-xl border border-border bg-background">
1383+
<div class="flex items-center justify-between">
1384+
<span class="text-xs font-bold uppercase tracking-wider text-primary">
1385+
1. Main Post (No External Link = Max Reach)
1386+
</span>
1387+
</div>
1388+
<pre class="text-xs font-mono whitespace-pre-wrap text-foreground bg-muted/40 p-3 rounded-lg border border-border select-all">{`Joined @CodingCatDev to break down ${portalData.topics || `${portalData.companyName} architecture in production`}.\n\nWe walked through the real mental model, architecture diagram, and live code (plus where the sharp edges live in production).\n\nFull video walkthrough is linked in the first reply 👇`}</pre>
1389+
</div>
1390+
1391+
<div class="flex flex-col gap-2 p-4 rounded-xl border border-border bg-background">
1392+
<div class="flex items-center justify-between">
1393+
<span class="text-xs font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400">
1394+
2. Reply #1 (YouTube Continuous Watch Session Link)
1395+
</span>
1396+
</div>
1397+
<pre class="text-xs font-mono whitespace-pre-wrap text-foreground bg-muted/40 p-3 rounded-lg border border-border select-all">{`Watch the full deep dive on @CodingCatDev YouTube (and subscribe to help hit 100K!): https://www.youtube.com/@codingcatdev?sub_confirmation=1\n\nSpeaker profile & show notes: https://codingcat.dev/guest/${portalData.guestSlug || "guest"}`}</pre>
1398+
</div>
1399+
</div>
1400+
</section>
1401+
13541402
<!-- Verified First-Party Telemetry Strip -->
13551403
<section class="grid grid-cols-1 sm:grid-cols-4 gap-4 p-5 rounded-2xl border border-border bg-card/60">
13561404
<div class="flex flex-col gap-1">
13571405
<span class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">YouTube Subscribers</span>
1358-
<span class="text-2xl font-bold text-foreground">61.2K+</span>
1359-
<span class="text-xs text-primary font-medium">✓ Verified YouTube API</span>
1406+
<span class="text-2xl font-bold text-foreground">62.5K+</span>
1407+
<span class="text-xs text-primary font-medium">✓ Verified YouTube API (Goal: 100K)</span>
13601408
</div>
13611409
<div class="flex flex-col gap-1">
13621410
<span class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">US / CA / UK / AU Share</span>

‎apps/site/src/pages/post/[slug].astro‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import CoverMedia from "@/components/CoverMedia.astro";
66
import ExcalidrawBlueprintCard from "@/components/ExcalidrawBlueprintCard.astro";
77
import FormattedDate from "@/components/FormattedDate.astro";
88
import PortableTextContent from "@/components/portable-text/PortableTextContent.astro";
9+
import PtYouTube from "@/components/portable-text/PtYouTube.astro";
910
import SectionHeader from "@/components/SectionHeader.astro";
1011
import SponsorCard from "@/components/SponsorCard.astro";
1112
import TranscriptModal from "@/components/TranscriptModal.astro";
@@ -52,6 +53,20 @@ const transcriptText =
5253
const matchedTopics = matchTopicsForText(
5354
`${post.title ?? ""} ${post.excerpt ?? ""}`,
5455
);
56+
const isSanityTopic = matchedTopics.some((t) => t.slug === "sanity");
57+
const fallbackRelatedVideo = isSanityTopic
58+
? {
59+
title: "Naive Vector RAG vs. Sanity Context Knowledge Bases",
60+
youtube: "https://youtu.be/gH9Q6-b1b4Y",
61+
description:
62+
"See how structured knowledge bases and MCP context beat brittle chunking pipelines in production.",
63+
}
64+
: {
65+
title: "3,000 AI Images for $1: Dockerless Serverless GPUs in TypeScript",
66+
youtube: "https://youtu.be/7d6iJHEPMZI",
67+
description:
68+
"Watch the full architecture walkthrough and TypeScript implementation on the @CodingCatDev YouTube channel.",
69+
};
5570
const videoSchema = post.youtube
5671
? videoObjectSchema(
5772
origin,
@@ -195,6 +210,31 @@ const faqNode = faqSchema(extractFaqsFromPortableText(post.content));
195210
)
196211
}
197212

213+
{
214+
!post.youtube && (
215+
<section class="my-10 rounded-3xl border-2 border-[#2A1155] bg-[#FAF9FC] p-6 shadow-sketch dark:border-white/25 dark:bg-[#131B2E]">
216+
<div class="mb-4 flex flex-wrap items-center justify-between gap-3">
217+
<div>
218+
<span class="inline-flex items-center gap-1.5 rounded-full border border-[#FF0000]/40 bg-[#FF0000]/10 px-3 py-0.5 font-mono text-[11px] font-extrabold uppercase tracking-wider text-[#DC2626] dark:border-[#FF0000]/50 dark:bg-[#FF0000]/20 dark:text-red-300">
219+
▶ Watch on @CodingCatDev YouTube
220+
</span>
221+
<h2 class="mt-2 font-display text-2xl font-black text-[#2A1155] dark:text-white">
222+
Watch the Related Video Deep Dive: {fallbackRelatedVideo.title}
223+
</h2>
224+
<p class="mt-1 text-sm font-medium text-[#2A1155]/75 dark:text-slate-300">
225+
{fallbackRelatedVideo.description}
226+
</p>
227+
</div>
228+
</div>
229+
<PtYouTube
230+
node={{ _type: "youtube", youtube: fallbackRelatedVideo.youtube }}
231+
index={0}
232+
isInline={false}
233+
/>
234+
</section>
235+
)
236+
}
237+
198238
<ExcalidrawBlueprintCard title={post.title} kind="post" />
199239

200240
<PortableTextContent

0 commit comments

Comments
 (0)