diff --git a/.gitignore b/.gitignore index 5cca4cb..cf9e327 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ AGENTS.md # generated collections src/data/collections.generated.ts +src/img/events/originals/ diff --git a/src/components/sponsor/CaseStudyVideo.astro b/src/components/sponsor/CaseStudyVideo.astro new file mode 100644 index 0000000..22fc303 --- /dev/null +++ b/src/components/sponsor/CaseStudyVideo.astro @@ -0,0 +1,39 @@ +--- +export interface Props { + class?: string; +} + +const { class: className } = Astro.props; +--- + +
+ +
+ + diff --git a/src/components/sponsor/PartnerCard.astro b/src/components/sponsor/PartnerCard.astro new file mode 100644 index 0000000..7bcabc1 --- /dev/null +++ b/src/components/sponsor/PartnerCard.astro @@ -0,0 +1,62 @@ +--- +import type { Partner } from 'src/data/sponsor'; + +export interface Props { + partner: Partner; + class?: string; +} + +const { partner, class: className } = Astro.props; + +const svgs = import.meta.glob('/src/img/sponsors/*.svg', { + query: '?raw', + import: 'default' +}); +--- + +
+
+
+ +
+

+ + {partner.name} + +

+
+ +

+ {partner.blurb} +

+ + { + partner.caseStudy && ( + + See the 90-day results + + + ) + } +
diff --git a/src/components/sponsor/XPostCard.astro b/src/components/sponsor/XPostCard.astro new file mode 100644 index 0000000..ae0535a --- /dev/null +++ b/src/components/sponsor/XPostCard.astro @@ -0,0 +1,162 @@ +--- +import type { ImageMetadata } from 'astro'; +import { Image } from 'astro:assets'; + +import type { XPost } from 'src/data/sponsor'; +import { getShowInfo } from 'src/lib/rss'; + +export interface Props { + post: XPost; + class?: string; +} + +const { post, class: className } = Astro.props; + +const avatars = import.meta.glob<{ default: ImageMetadata }>( + '/src/img/people/*.{jpeg,jpg,png}' +); + +const show = await getShowInfo(); +--- + + +
+ { + post.avatar ? ( + + ) : ( + + ) + } + +
+

+ + {post.author} + +

+

+ @{post.handle} · {post.date} +

+
+ + +
+ +

+ {post.text} +

+ +
+ { + post.replies && ( + + + {post.replies} + + ) + } + { + post.reposts && ( + + + {post.reposts} + + ) + } + { + post.likes && ( + + + {post.likes} + + ) + } + + + {post.views} views + +
+
diff --git a/src/data/sponsor.ts b/src/data/sponsor.ts new file mode 100644 index 0000000..85f5393 --- /dev/null +++ b/src/data/sponsor.ts @@ -0,0 +1,258 @@ +/** + * Shared content for the sponsor page variants. + * + * Every number and post here was verified against the live public profiles + * on 2026-08-21. To feature different X posts, replace entries in `xPosts` + * with the real text/metrics and paste the exact status permalink into `url`. + */ + +export interface XPost { + author: string; + handle: string; + /** Filename under src/img/people/, or null to use the show artwork. */ + avatar: string | null; + date: string; + text: string; + replies?: string; + reposts?: string; + likes?: string; + views: string; + url: string; +} + +export const xPosts: Array = [ + { + author: 'Whiskey Web and Whatnot', + handle: 'whiskeywebfm', + avatar: null, + date: 'Dec 29, 2023', + text: 'Are you team inferred types or team explicit types? @kenwheeler knows where he stands.', + replies: '6', + reposts: '12', + likes: '178', + views: '284.8K', + url: 'https://x.com/whiskeywebfm/status/1740841143670280596' + }, + { + author: 'Whiskey Web and Whatnot', + handle: 'whiskeywebfm', + avatar: null, + date: 'Feb 20, 2024', + text: "Is there anything Microsoft doesn't own these days? We discuss the powerful reach of our Microsoft overlords with @chriscoyier on the latest WWW episode.", + replies: '9', + reposts: '7', + likes: '201', + views: '148.9K', + url: 'https://x.com/whiskeywebfm/status/1760098830463148485' + }, + { + author: 'Robbie Wagner', + handle: 'RobbieWagner', + avatar: 'robbiethewagner.jpg', + date: 'Sep 27, 2023', + text: 'React was a mistake', + replies: '122', + reposts: '38', + likes: '483', + views: '127.4K', + url: 'https://x.com/RobbieWagner/status/1707128750746243477' + }, + { + author: 'Adam Argyle', + handle: 'argyleink', + avatar: 'argyleink.jpg', + date: 'Feb 3, 2026', + text: 'Wild how far you can push "customizable select" with just #CSS', + replies: '45', + reposts: '74', + likes: '1.6K', + views: '100K', + url: 'https://x.com/argyleink/status/2018737944622944378' + }, +]; + +export interface ReachStat { + value: string; + /** For the count-up animation: numeric target and suffix. */ + target: number; + suffix: string; + label: string; + detail: string; +} + +export const reachStats: Array = [ + { + value: '100K+', + target: 100, + suffix: 'K+', + label: 'Monthly impressions', + detail: 'Across audio, video, and social' + }, + { + value: '76K+', + target: 76, + suffix: 'K+', + label: 'Combined X followers', + detail: '@argyleink 58.5K · @whiskeywebfm 10.9K · @RobbieWagner 7.1K' + }, + { + value: '10.9K', + target: 10.9, + suffix: 'K', + label: 'YouTube subscribers', + detail: '339 videos and counting' + }, + { + value: '10K', + target: 10, + suffix: 'K', + label: 'Downloads per episode', + detail: '3–10K, top 10% of podcasts' + } +]; + +export interface HostProfile { + name: string; + handle: string; + avatar: string; + followers: string; + role: string; + creds: Array; + url: string; +} + +export const hostProfiles: Array = [ + { + name: 'Robbie Wagner', + handle: 'RobbieWagner', + avatar: 'robbiethewagner.jpg', + followers: '7.1K', + role: 'Co-host · Whiskey buyer-in-chief', + creds: [ + 'Slings JavaScript at HashiCorp', + 'Previously Amazon, Netflix, and Apple', + 'Founder of Ship Shape' + ], + url: 'https://x.com/RobbieWagner' + }, + { + name: 'Adam Argyle', + handle: 'argyleink', + avatar: 'argyleink.jpg', + followers: '58.5K', + role: 'Co-host · Resident CSS dork', + creds: [ + 'Design engineer at Shopify, prior Google Chrome', + 'CSS Working Group · co-hosted The CSS Podcast', + 'Maker of Open Props and gradient.style' + ], + url: 'https://x.com/argyleink' + } +]; + +export interface Partner { + id: string; + name: string; + img: string; + url: string; + blurb: string; + caseStudy?: string; +} + +export const partners: Array = [ + { + id: 'warp', + name: 'Warp', + img: 'warp.svg', + url: 'https://warp.dev/', + blurb: + 'The AI-first terminal. Ran 90 days of host-read spots across audio, video, and social.', + caseStudy: '/sponsors/warp' + }, + { + id: 'code-rabbit', + name: 'CodeRabbit', + img: 'code-rabbit.svg', + url: 'http://coderabbit.link/whiskey', + blurb: 'AI code review on every pull request, read to the devs who ship them.' + }, + { + id: 'gitkraken', + name: 'GitKraken', + img: 'gitkraken.svg', + url: 'https://gitkraken.com/whiskeyfm', + blurb: 'Git tooling developers actually like — a natural fit for our audience.' + }, + { + id: 'norlan', + name: 'Norlan', + img: 'norlan.svg', + url: 'https://norlanglass.com/', + blurb: 'Design-forward whiskey glassware. Literally the glass on our table.' + }, + { + id: 'cascadiajs', + name: 'CascadiaJS', + img: 'cascadiajs.svg', + url: 'https://cascadiajs.com', + blurb: 'The Pacific Northwest web conference — where we emceed on stage in 2026.' + } +]; + +export const adPackages = [ + { + bullets: [ + 'Have a bottle of whiskey or software product reviewed', + 'Honest, positive mention during Whiskey and/or Whatnot segments' + ], + heading: 'The Drop', + price: '$250', + envKey: 'POLAR_BOTTLEDROP_PRODUCT_ID' + }, + { + bullets: [ + 'Ad on our website or in the show notes', + 'Placed prominently on main page and show notes', + 'Consistent exposure outside of the audio feed' + ], + heading: 'The Label', + price: '$250', + envKey: 'POLAR_LABEL_PRODUCT_ID' + }, + { + bullets: ['A baked in, high-trust host read pre-roll ad', '30-seconds'], + heading: "The Distiller's Cut", + price: '$500', + envKey: 'POLAR_30SEC_PRODUCT_ID' + }, + { + bullets: ['A baked in, high-trust host read pre-roll ad', '60-seconds'], + heading: "The Spirit Maker's Cut", + price: '$1k', + envKey: 'POLAR_60SEC_PRODUCT_ID' + }, + { + bullets: [ + '4x 30-second host-read ads', + '4x website & show notes placements', + 'Perfect for consistent monthly presence' + ], + heading: 'The Crate', + price: '$2.4k', + period: 'per month', + envKey: 'POLAR_CRATE_PRODUCT_ID' + }, + { + bullets: [ + 'Our flagship monthly sponsorship', + '4x 60-second host-read ads', + '4x website & show notes placements', + '"Presented By [Your Company]" in episode titles', + 'Social media mentions for each episode' + ], + heading: 'The Full Barrel', + price: '$4k', + period: 'per month', + envKey: 'POLAR_FULLBARREL_PRODUCT_ID' + } +]; diff --git a/src/img/events/adam-cascadiajs-keynote.jpg b/src/img/events/adam-cascadiajs-keynote.jpg new file mode 100644 index 0000000..8f79971 Binary files /dev/null and b/src/img/events/adam-cascadiajs-keynote.jpg differ diff --git a/src/img/events/adam-live-shaundai.jpg b/src/img/events/adam-live-shaundai.jpg new file mode 100644 index 0000000..ae9a63c Binary files /dev/null and b/src/img/events/adam-live-shaundai.jpg differ diff --git a/src/img/events/cascadiajs-crowd-hands.jpg b/src/img/events/cascadiajs-crowd-hands.jpg new file mode 100644 index 0000000..5aa1ed6 Binary files /dev/null and b/src/img/events/cascadiajs-crowd-hands.jpg differ diff --git a/src/img/events/hosts-cascadiajs-podium.jpg b/src/img/events/hosts-cascadiajs-podium.jpg new file mode 100644 index 0000000..62b1a58 Binary files /dev/null and b/src/img/events/hosts-cascadiajs-podium.jpg differ diff --git a/src/img/events/robbie-cascadiajs-podium.jpg b/src/img/events/robbie-cascadiajs-podium.jpg new file mode 100644 index 0000000..48632ce Binary files /dev/null and b/src/img/events/robbie-cascadiajs-podium.jpg differ diff --git a/src/pages/sponsor/cover-story.astro b/src/pages/sponsor/cover-story.astro new file mode 100644 index 0000000..7ad9d31 --- /dev/null +++ b/src/pages/sponsor/cover-story.astro @@ -0,0 +1,410 @@ +--- +import { Image } from 'astro:assets'; + +import Layout from '../../layouts/Layout.astro'; +import AdPackageCard from '../../components/AdPackageCard.astro'; +import XPostCard from '../../components/sponsor/XPostCard.astro'; +import CaseStudyVideo from '../../components/sponsor/CaseStudyVideo.astro'; +import { + adPackages, + hostProfiles, + partners, + xPosts +} from 'src/data/sponsor'; + +import coverPhoto from '../../img/events/adam-cascadiajs-keynote.jpg'; +import spreadPhoto from '../../img/events/hosts-cascadiajs-podium.jpg'; +import robbiePhoto from '../../img/events/robbie-cascadiajs-podium.jpg'; +import livePhoto from '../../img/events/adam-live-shaundai.jpg'; +import crowdPhoto from '../../img/events/cascadiajs-crowd-hands.jpg'; + +const [robbie, adam] = hostProfiles; +const featuredPosts = [xPosts[0], xPosts[2]]; +--- + + + + +
+ + +
+

+ Whiskey Web & Whatnot +

+

The Sponsor Issue · 2026

+
+ +
+
+ Adam Argyle giving a talk at CascadiaJS 2026 beneath stained-glass windows +
+
+ + + Partner with us + + +
+

+ The two developers your audience already follows +

+

+ 58.5K and 7.1K followers on X. 10.9K YouTube subscribers. A top + 10% podcast. And a whiskey budget that is, frankly, out of + control. +

+
+
+
+ +
+

+ Robbie Wagner and Adam Argyle record Whiskey Web and Whatnot every + week: a whiskey-fueled fireside chat about AI, the modern web, and + the humans behind the code. Sponsoring the show doesn't buy a slot on + a spreadsheet — it buys these two, on the record, telling their + audience about you. +

+

+ Photography from CascadiaJS 2026, Seattle — where the hosts emceed on + the mainstage. +

+
+ +
+
+

+ Start with who they are. Robbie slings JavaScript at HashiCorp and + slung it for Amazon, Netflix, and Apple before that; he also runs + the consultancy Ship Shape. Adam is a design engineer at Shopify by + way of Google Chrome, sits in the CSS Working Group, co-hosted The + CSS Podcast, and built Open Props and gradient.style. When one of + them says your product is good, senior engineers hear it from + someone whose code they already use. +

+

+ The show blends technical depth with premium lifestyle content — + web development, software architecture, and fine whiskey, rated on + an extremely scientific tentacle scale. The audience skews senior: + engineering managers, architects, web and backend developers, half + of them in the US, the rest spread from the UK to Australia. +

+
+

+ “Host-read ads are baked into the episode forever. Your spot is + still converting when the episode is three years old.” +

+
+

+ That's the mechanism: no programmatic insertion, no ephemeral + banner. The hosts read every spot themselves, in their own voice, + inside content that keeps getting downloaded — 3 to 10 thousand + times per episode, over 100 thousand impressions a month once + video and social do their rounds. +

+
+ + +
+ +
+
+
+ Robbie Wagner and Adam Argyle sharing a bottle of bourbon at the CascadiaJS podium +
+
+ The hosts and the evening's research material, CascadiaJS 2026. +
+
+ +
+
+
+ Robbie Wagner speaking at the CascadiaJS podium +
+
+ Robbie announcing the conference's layoff-relief donation. +
+
+
+
+ Adam Argyle recording a live episode with Shaundai Person +
+
+ Recording live with Shaundai Person — the show tours conference + floors. +
+
+
+
+ +
+

+ As seen on your feed +

+
+ {featuredPosts.map((post) => )} +
+
+ +
+

+ Case in point: Warp ran 90 days with us +

+

+ Hear what a host-read campaign sounds like when it's baked into the + feed. +

+ + + See the 90-day results + + +
+ +
+

+ Previously featuring +

+ +
+ +
+
+

+ The rate card +

+

Self-serve · host-read · evergreen

+
+ +
+ { + adPackages.map((pkg) => ( + + )) + } +
+
+ +
+ The CascadiaJS audience raising hands during the hosts' session +
+
+
+

+ Have an idea that isn't on the rate card? +

+

+ The weird ones are usually our favorites. We're down to chat. +

+ + + Pitch us your idea + + +

+ — Robbie & Adam, Whiskey Web and Whatnot +

+
+
+
+
+ +