PageSourceSearch

https://www.demandcurve.com/

html demandcurve.com collected 2026-10-02 03:38:54 UTC 117,459 bytes, 806 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Demand Curve | The AI-Powered Growth Agency for Startups</title><meta name="description" content="Demand Curve is the growth agency for startups. Powered by senior operators and proprietary AI. Partner to 7,000+ startups, backed by Y Combinator."><meta name="theme-color" content="#004AFF"><link rel="icon" type="image/png" href="/assets/brand/favicon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/brand/favicon-32.png"><link rel="apple-touch-icon" href="/assets/brand/apple-touch-icon.png"><link rel="canonical" href="https://www.demandcurve.com"><meta property="og:type" content="website"><meta property="og:site_name" content="Demand Curve"><meta property="og:title" content="Demand Curve | The AI-Powered Growth Agency for Startups"><meta property="og:description" content="Demand Curve is the growth agency for startups. Powered by senior operators and proprietary AI. Partner to 7,000+ startups, backed by Y Combinator."><meta property="og:url" content="https://www.demandcurve.com"><meta property="og:image" content="https://www.demandcurve.com/assets/brand/og-default.jpg"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Demand Curve | The AI-Powered Growth Agency for Startups"><meta name="twitter:description" content="Demand Curve is the growth agency for startups. Powered by senior operators and proprietary AI. Partner to 7,000+ startups, backed by Y Combinator."><meta name="twitter:image" content="https://www.demandcurve.com/assets/brand/og-default.jpg"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600&display=swap" rel="stylesheet"><link href="/v2.css" rel="stylesheet">
1<script type="application/ld+json">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "You say you’ve rebuilt the agency model. What’s actually different?", "acceptedAnswer": {"@type": "Answer", "text": "Traditional agencies aren’t built for startups. They’re built for big clients and their own margin, which means an army of junior account managers, standardized playbooks, and bloated meeting cycles. Worse, they’re built to sell, not deliver. You meet their polished executives during the sales process, hear all about the awards they’ve won and how elite their team is, and sign. Then, unbeknownst to you, you’re handed to a junior team, shielded behind an account manager who’s really a salesperson in a strategist’s clothing. Meanwhile startups sit at the bottom of the priority list while the senior people stay on the bigger accounts. We flipped that model on its head. Everyone here is a senior growth expert, no juniors, no middlemen, not even in sales. The people you talk to from day one are the real deal. And our terms prove it: most agencies lock you into long contracts because it’s the only way to keep clients they know they’ll underdeliver for. We work month to month. We’d rather earn your business every single month than trap you in a year of work we haven’t earned yet."}}, {"@type": "Question", "name": "What makes you startup growth experts specifically?", "acceptedAnswer": {"@type": "Answer", "text": "Here’s the dirty secret of our industry: growth at a big company isn’t that hard. The machine already works, the budgets are huge, the data goes back years. It’s mostly optimization, running playbooks someone else already wrote. But who wrote those playbooks to begin with? Inventing what works from scratch, with no machine and every dollar counting, is the hard part. That’s why startup growth is so difficult, and why so few people are truly great at it. But those are the only people we hire."}}, {"@type": "Question", "name": "Everyone claims to use AI now. How is Signal different?", "acceptedAnswer": {"@type": "Answer", "text": "Most agencies are wrapping the same off-the-shelf tools everyone else has, trained on the same public data, so they get the same average outputs. Signal is our own AI, trained on a decade of data no one else has from 7,000+ startups, our Growth Engine methodology, and a community of 100,000+ operators sharing what’s working directly from the front lines. It gives our strategists superpowers, helping them move faster and spot opportunities they’d never spot alone, while the highest-leverage work, the strategy and the hard problems, stays firmly with our people."}}, {"@type": "Question", "name": "What do you mean by “built-in distribution”?", "acceptedAnswer": {"@type": "Answer", "text": "Any agency can manage your channels. But how many are a distribution channel themselves? We are. Our newsletter reaches 100,000+ founders and operators, and our broader media property, The Frontier, reaches over a million people a year. But the real value isn’t the reach, it’s the trust. We’ve been one of the most trusted voices in startup growth for a decade, and the people in our world put weight on what we recommend. We can bring you into that world: a high-trust distribution channel that would take a decade to build yourself, and one that no other growth partner can offer."}}, {"@type": "Question", "name": "Who do you work with?", "acceptedAnswer": {"@type": "Answer", "text": "Our sweet spot is a startup entering or already in its growth stage, typically Series A through C, or a bootstrapped company producing at least seven figures in revenue with healthy margins. Usually the job is one of three: building your first scalable growth engine, breaking through a ceiling you’ve hit, or layering new engines onto the one that got you here. On the vertical side, our bread and butter is consumer tech (software and hardware), B2B tech, and DTC. About the only company we’re not built for is a pure enterprise sales model with no marketing-led motion."}}, {"@type": "Question", "name": "We’re early-stage and still searching for product-market fit. Can you help?", "acceptedA
1nswer": {"@type": "Answer", "text": "Yes. We’re startup people through and through, and we believe what most people call a product-market fit problem is usually a growth problem in disguise. When a startup fails, the autopsy almost always points at the product. But the real issue is upstream: they never understood that growth has to be engineered into the DNA of the business, and that the product is only one piece of it. They bolted growth on as an afterthought, and it showed. They never got the right market in front of the product to even judge fit. They never told a story that made that market understand its true value. They never shaped the product around the channel that should have carried it, or built a revenue model that channel could support. Each of those is a growth decision, made too late or not at all. So yes, we work with early-stage startups, and when we say we architect growth into your DNA from the start, this is exactly what we mean."}}]}</script>
1<script type="importmap">{ "imports": { "three": "https://esm.sh/[email protected]" } }</script>
1<!-- Consent + analytics: ONE shared component (also used by FrontierShell) -->
1<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"Demand Curve","url":"https://www.demandcurve.com","logo":{"@type":"ImageObject","url":"https://www.demandcurve.com/assets/brand/apple-touch-icon.png"},"description":"Demand Curve is a Y Combinator-backed growth agency for startups. Senior growth operators, amplified by AI, run paid marketing, AI search optimization, ChatGPT ads, positioning, ad creative, and landing pages. Demand Curve also publishes The Frontier, a free growth newsletter and content hub read by 100,000+ founders and operators.","sameAs":["https://www.linkedin.com/company/demandcurve/","https://x.com/GrowthTactics","https://www.ycombinator.com/companies/demand-curve"]}</script>
1<script type="text/javascript">
2  var _conv_page_type = "";
3  var _conv_category_id = "";
4  var _conv_category_name = "";
5  var _conv_product_sku = "";
6  var _conv_product_name = "";
7  var _conv_product_price = "";
8  var _conv_customer_id = "";
9  var _conv_custom_v1 = "";
10  var _conv_custom_v2 = "";
11  var _conv_custom_v3 = "";
12  var _conv_custom_v4 = "";
13</script>
13<script type="text/javascript" src="//cdn-4.convertexperiments.com/v1/js/100110038-100110404.js?environment=production"></script>
13<script async defer src="https://tools.luckyorange.com/core/lo.js?site-id=ffaf86de"></script>
13<script src="https://js.sentry-cdn.com/40eba149d5d3cd2d50e3ce3e8596fd67.min.js" crossorigin="anonymous"></script>
13<script>
14var _iub = _iub || [];
15_iub.csConfiguration = {"applyGdprForCH":false,"askConsentAtCookiePolicyUpdate":true,"countryDetection":true,"emailMarketing":{"theme":"dark"},"enableFadp":true,"enableLgpd":true,"enableUspr":true,"floatingPreferencesButtonDisplay":false,"gdprAppliesGlobally":false,"lgpdAppliesGlobally":false,"perPurposeConsent":true,"siteId":2090586,"storage":{"useSiteId":true},"whitelabel":true,"cookiePolicyId":41182736,"banner":{"acceptButtonDisplay":true,"closeButtonDisplay":false,"customizeButtonDisplay":true,"listPurposes":true,"ownerName":"Demand Curve","position":"float-bottom-left","rejectButtonDisplay":true,"showTitle":false,"usesThirdParties":false}};
16_iub.csLangConfiguration = {"en":{"cookiePolicyId":41182736}};
17</script>
17<script>(function(){const segKeyProd = "mhWzK1ldCPnFTAGyhn5JOfuvZw35b6o5";
18const segKeyDev = "";
19
20window.DC_SEGMENT_KEY_PROD = segKeyProd; window.DC_SEGMENT_KEY_DEV = segKeyDev;
21})();</script>
21<script src="/dc-analytics.js"></script>
21<script type="text/javascript" src="//cs.iubenda.com/sync/2090586.js"></script>
21<script type="text/javascript" src="//cdn.iubenda.com/cs/gpp/stub.js"></script>
21<script type="text/javascript" src="//cdn.iubenda.com/cs/iubenda_cs.js" charset="UTF-8" async></script>
21</head><body><!-- Page-wide film grain (covers every section, sits under the nav) --><canvas class="noise-canvas" width="1024" height="1024"></canvas><!-- second grain layer: multiply, shows on the white sections --><canvas class="noise-canvas noise-canvas--mult" width="1024" height="1024"></canvas><!-- NAV: vertical stacked list (hero state) --><nav class="nav-stacked"><a class="wordmark" href="/">Demand Curve</a><button class="navlink nav-trigger" type="button" data-menu="programs" aria-haspopup="true" aria-expanded="false" aria-controls="mega-programs">Services <span class="nav-caret" aria-hidden="true">&#9662;</span></button><a class="navlink" href="/about">About</a><button class="navlink nav-trigger" type="button" data-menu="company" aria-haspopup="true" aria-expanded="false" aria-controls="mega-company">Company <span class="nav-caret" aria-hidden="true">&#9662;</span></button><a class="navlink" href="/newsletter">Growth Newsletter</a><a class="navlink" href="/frontier">The Frontier<span class="nav-ext" aria-hidden="true">&#8599;</span></a></nav><!-- NAV: horizontal sticky bar (scrolled state, fades in) --><nav class="nav-bar"><a class="wordmark wordmark--bar" href="/">Demand Curve</a><button class="navlink nav-trigger" type="button" data-menu="programs" aria-haspopup="true" aria-expanded="false" aria-controls="mega-programs">Services <span class="nav-caret" aria-hidden="true">&#9662;</span></button><a class="navlink" href="/about">About</a><button class="navlink nav-trigger" type="button" data-menu="company" aria-haspopup="true" aria-expanded="false" aria-controls="mega-company">Company <span class="nav-caret" aria-hidden="true">&#9662;</span></button><a class="navlink" href="/newsletter">Growth Newsletter</a><a class="navlink" href="/frontier">The Frontier<span class="nav-ext" aria-hidden="true">&#8599;</span></a><a class="nav-contact" href="/contact">Let&#39;s talk</a></nav><!-- CTA: Let's talk (top-right) — stripes + corner brackets, fills solid on hover --><a class="cta" href="/contact"><canvas class="cta-noise" width="160" height="64"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Let&#39;s talk</span></a><!-- MOBILE NAV: hamburger bar + full-screen menu (≤768px) --><div class="mobile-bar"><a class="wordmark" href="/">Demand Curve</a><a class="nav-contact mobile-cta" href="/contact">Let&#39;s talk</a><button class="nav-toggle" type="button" aria-label="Open menu" aria-expanded="false" aria-controls="mobile-menu"><span class="nav-toggle-bar"></span><span class="nav-toggle-bar"></span></button></div><nav class="mobile-menu" id="mobile-menu" aria-label="Mobile navigation" aria-hidden="true"><span class="mm-label">Services</span><div class="mm-sub"><a style="--accent:#0ADBFE" href="/paid-marketing"><img loading="lazy" class="mm-art" src="/engravings/target.png" alt="">Paid Marketing</a><a style="--accent:#10B981" href="/ai-search"><img loading="lazy" class="mm-art" src="/engravings/lighthouse.png" alt="">AI Search</a><a style="--accent:#FE052C" href="/chatgpt-ads"><img loading="lazy" class="mm-art" src="/engravings/pigeon.png" alt="">ChatGPT Ads</a><a style="--accent:#FE05AF" href="/story-systems"><img loading="lazy" class="mm-art" src="/engravings/quill.png" alt="">Story Systems</a><a style="--accent:#FD9905" href="/ad-creative"><img loading="lazy" class="mm-art" src="/engravings/gtm-tools.png" alt="">Ad Creative</a><a style="--accent:#5B3FD6" href="/landing-pages"><img loading="lazy" class="mm-art" src="/engravings/landing.png" alt="">Landing Pages</a></div><span class="mm-label">Company</span><div class="mm-sub"><a class="mm-sub--plain" href="/about"><img loading="lazy" class="mm-art" src="/engravings/dc-model.png" alt="">About</a><a class="mm-sub--plain" href="/sponsorships"><img loading="lazy" class="mm-art" src="/engravings/handshake.png" alt="">Sponsorships</a><a class="mm-sub--plain" href="/careers"><img loading="lazy" class="mm-art" src="/engravings/key.png" alt="">Careers</a></div><a href="/newsletter"><img loading="lazy" class="mm-art" src="/engravings/press.png" alt="">Growth Newsletter</a><a href="/frontier"><img loading="lazy" class="mm-art" src="/engravings/frontier.png" alt="">The Frontier<span class="nav-ext" aria-hidden="true">&#8599;</span></a><a class="mm-cta" href="/contact">Let's talk</a></nav><div class="robot-peek-wrap" aria-hidden="true"><div class="robot-peek"><img class="rf rf1" src="/engravings/robot-wave-1.png" alt="" loading="lazy"><img class="rf rf2" src="/engravings/robot-wave-2.png" alt="" loading="lazy"></div></div><!-- MEGA-MENU: shared dropdown sheet, opened from either the vertical nav or the bar --><div class="mega" aria-hidden="true"><div class="mega-scrim"></div><div class="mega-panel" id="mega-programs" data-panel="programs" role="region" aria-label="Services"><div class="mega-inner"><span class="mega-eyebrow">Services</span><div class="mega-grid mega-grid--programs"><a class="mega-card" style="--accent:#0ADBFE" href="/paid-marketing"><img class="mega-art" src="/engravings/target.png" alt="" loading="lazy"><span class="mega-card-name">Paid Marketing</span><span class="mega-card-desc">We architect and scale paid marketing engines.</span></a><a class="mega-card" style="--accent:#FE05AF" href="/story-systems"><img class="mega-art" src="/engravings/quill.png" alt="" loading="lazy"><span class="mega-card-name">Story Systems</span><span class="mega-card-desc">Messaging so good prospects show up already sold.</span></a><a class="mega-card" style="--accent:#10B981" href="/ai-search"><img class="mega-art" src="/engravings/lighthouse.png" alt="" loading="lazy"><span class="mega-card-name">AI Search</span><span class="mega-card-desc">Be the answer when buyers ask AI who to trust.</span></a><a class="mega-card" style="--accent:#FD9905" href="/ad-creative"><img class="mega-art" src="/engravings/gtm-tools.png" alt="" loading="lazy"><span class="mega-card-name">Ad Creative</span><span class="mega-card-desc">Human-directed creative, tested and scaled on real spend.</span></a><a class="mega-card" style="--accent:#5B3FD6" href="/landing-pages"><img class="mega-art" src="/engravings/landing.png" alt="" loading="lazy"><span class="mega-card-name">Landing Pages</span><span class="mega-card-desc">Landing pages designed to convert.</span></a><a class="mega-card" style="--accent:#FE052C" href="/chatgpt-ads"><img class="mega-art" src="/engravings/pigeon.png" alt="" loading="lazy"><span class="mega-card-name">ChatGPT Ads</span><span class="mega-card-desc">Reach high-intent buyers inside ChatGPT.</span></a></div><a class="mega-all" href="/services">See all services <span class="arrow">&#8594;</span></a></div></div><div class="mega-panel" id="mega-company" data-panel="company" role="region" aria-label="Company"><div class="mega-inner"><span class="mega-eyebrow">Company</span><div class="mega-grid mega-grid--company"><a class="mega-card mega-card--plain" href="/sponsorships"><img class="mega-art" src="/engravings/handshake.png" alt="" loading="lazy"><span class="mega-card-name">Sponsorships</span><span class="mega-card-desc">Partner with The Frontier to reach founders and operators.</span></a><a class="mega-card mega-card--plain" href="/careers"><img class="mega-art" src="/engravings/key.png" alt="" loading="lazy"><span class="mega-card-name">Careers</span><span class="mega-card-desc">1 open role on the growth team.</span></a></div></div></div></div><section class="hero" data-theme="blue"><h1 class="hero-title"><span class="word-mask"><span class="word">We</span></span><span class="word-mask"><span class="word">Grow</span></span><span class="word-mask"><span class="word">Startups</span></span></h1><div class="hero-foot"><span>The Growth Agency</span><span>Trusted by 7,000+ startups</span></div></section><section class="adv" data-theme="blue"><div class="section-wrap"><div class="adv-head"><h2 class="adv-title display-head">Demand Curve is the<br>growth agency for startups.</h2><p class="adv-intro">Growth has always favored the incumbents with endless budgets, known brands, and access to the best talent. So we rebuilt the agency model to level the playing field.</p></div><div class="adv-grid"><article class="adv-pillar"><span class="adv-kicker">01 / The talent</span><span class="adv-fig">
21<img class="adv-art" src="/engravings/chess-king.png" alt="" loading="lazy"></span><h3 class="adv-name">Senior operators, startup specialists</h3><p class="adv-desc">We've assembled a team of rare operators. Ones who've dedicated their careers to the hardest startup problem: growth. Ones with a track record unlike anyone we know of.</p></article><article class="adv-pillar"><span class="adv-kicker">02 / The intelligence</span><span class="adv-fig"><img class="adv-art" src="/engravings/ai-oracle.png" alt="" loading="lazy"></span><h3 class="adv-name">Proprietary AI</h3><p class="adv-desc">Our own AI, trained on 7,000+ startups, multiplying everything our operators do.</p></article><article class="adv-pillar"><span class="adv-kicker">03 / The reach</span><span class="adv-fig"><img class="adv-art" src="/engravings/hailer.png" alt="" loading="lazy"></span><h3 class="adv-name">Built-in distribution</h3><p class="adv-desc">A distribution engine most agencies can't offer, putting you in front of the exact audience you'd spend years trying to reach.</p></article></div></div></section><section class="outgrown" data-theme="blue">    <div class="section-wrap"><p class="outgrown-line display-head"><span class="ol-mask"><span class="ol-line">You&rsquo;ve hit the ceiling of what in-house growth can do.</span></span><span class="ol-mask ol-mask-2"><span class="ol-line">We&rsquo;re what comes next.</span></span></p></div></section><section class="social" data-theme="blue"><div class="social-inner"><div class="social-head"><img loading="lazy" class="social-laurel" src="/engravings/laurel-left.png" alt="" aria-hidden="true"><div class="social-head-txt"><span class="overline">The Track Record</span><h2 class="display-head tr-cheeky">We&rsquo;ve grown a sh<span class="tr-ast">*</span>t ton of startups</h2></div><img loading="lazy" class="social-laurel social-laurel--r" src="/engravings/laurel-left.png" alt="" aria-hidden="true"></div><div class="stats-block"><div class="stats-grid"><div class="stat stat--art"><img class="stat-art" src="/engravings/unicorn-dither.png" alt="" loading="lazy"><div class="stat-copy"><span class="stat-num">43</span><span class="stat-label">Unicorns created</span></div></div><div class="stat stat--art"><img class="stat-art" src="/engravings/atm-cash.png" alt="" loading="lazy"><div class="stat-copy"><span class="stat-num">$3B+</span><span class="stat-label">Revenue generated</span></div></div><div class="stat stat--art"><img class="stat-art" src="/engravings/crt-three.png" alt="" loading="lazy"><div class="stat-copy"><span class="stat-num">$500M+</span><span class="stat-label">Media managed</span></div></div><div class="stat stat--art"><img class="stat-art" src="/engravings/rocket-launch.png" alt="" loading="lazy"><div class="stat-copy"><span class="stat-num">7,000+</span><span class="stat-label">Startups</span></div></div></div><div class="yc-tag"><img loading="lazy" alt="Y Combinator" src="/assets/yc/yc-face.avif"><span class="yc-txt">Backed by <strong>Y&nbsp;Combinator</strong></span></div></div></div><p class="social-sub">You'll recognize a few of these.</p><div class="marquee-wrap"><div class="marquee" style="--dur:52s"><div class="marquee__track"><div class="marquee__group"><button class="cs-link" type="button" data-cs="videogen">Videogen<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Microsoft</span><span>Segment</span><button class="cs-link" type="button" data-cs="firmpilot">FirmPilot<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Clearbit</span><span>Sentry</span><span>TechCrunch</span><span>Framer</span></div><div class="marquee__group" aria-hidden="true"><button class="cs-link" type="button" data-cs="videogen" tabindex="-1">Videogen<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Microsoft</span><span>Segment</span><button class="cs-link" type="button" data-cs="firmpilot" tabindex="-1">FirmPilot<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Clearbit</span><span>Sentry</span><span>TechCrunch</span><span>Framer</span></div></div></div><div class="marquee marquee--reverse" style="--dur:64s"><div class="marquee__track"><div class="marquee__group"><button class="cs-link" type="button" data-cs="snitcher">Snitcher<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>
21Outschool</span><span>Imperfect Foods</span><span>Perfect Keto</span><span>Pilot</span><span>mParticle</span><span>Tumblr</span><span>Outschool</span><span>Imperfect Foods</span></div><div class="marquee__group" aria-hidden="true"><button class="cs-link" type="button" data-cs="snitcher" tabindex="-1">Snitcher<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Outschool</span><span>Imperfect Foods</span><span>Perfect Keto</span><span>Pilot</span><span>mParticle</span><span>Tumblr</span><span>Outschool</span><span>Imperfect Foods</span></div></div></div><div class="marquee" style="--dur:58s"><div class="marquee__track"><div class="marquee__group"><button class="cs-link" type="button" data-cs="workos">WorkOS<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Ancestry</span><span>Newton</span><span>Feedly</span><span>AgelessRX</span><span>Envoy</span><span>
21Y Combinator</span><span>Ancestry</span><span>Newton</span></div><div class="marquee__group" aria-hidden="true"><button class="cs-link" type="button" data-cs="workos" tabindex="-1">WorkOS<svg class="cs-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" aria-hidden="true"><path d="M8 16 16 8M9.5 8H16v6.5"></path></svg></button><span>Ancestry</span><span>Newton</span><span>Feedly</span><span>AgelessRX</span><span>Envoy</span><span>Y Combinator</span><span>Ancestry</span><span>Newton</span></div></div></div></div></section><div class="seam" style="--from:#004AFF; --to:#171818"></div><section class="wif" data-theme="dark">    <div class="section-wrap"><span class="wif-kicker">Who it&rsquo;s for</span><h2 class="wif-title">You&rsquo;re in the right place if&hellip;</h2><ul class="wif-list"><li class="wif-row"><span class="wif-no">01</span><span class="wif-stmt">You&rsquo;re growing, but it isn&rsquo;t a repeatable system yet.</span></li><li class="wif-row"><span class="wif-no">02</span><span class="wif-stmt">You have a team, but no senior growth leadership steering it.</span></li><li class="wif-row"><span class="wif-no">03</span><span class="wif-stmt">You keep hitting growth problems your team hasn&rsquo;t solved before.</span></li><li class="wif-row"><span class="wif-no">04</span><span class="wif-stmt">You&rsquo;re outgrowing the growth resources you have in-house.</span></li><li class="wif-row"><span class="wif-no">05</span><span class="wif-stmt">You&rsquo;re carrying growth on your own, and you want a senior partner in it with you.</span></li><li class="wif-row"><span class="wif-no">06</span><span class="wif-stmt">You&rsquo;ve been burned by an agency that spent the budget but never moved the needle.</span></li></ul><div class="wif-foot"><p class="wif-foot-line">These are the problems we solve. Here&rsquo;s how.</p><img class="wif-hand" src="/engravings/manicule-down.png" alt="" loading="lazy"></div></div></section><section class="programs" data-theme="dark"><div class="section-wrap"><div class="programs-head"><span class="overline">Services</span><h2 class="display-head">AI-powered growth, done for you.</h2><p class="head-sub">Led by hand-picked, elite startup growth experts.</p></div><div class="svc-grid"><div class="svc-row"><a class="svc-card" style="--accent:#0ADBFE" href="/paid-marketing"><span class="svc-svc">Service I</span><div class="svc-name">Paid <br class="svc-wbr">Marketing</div><img class="svc-emb" src="/engravings/target.png" alt="" loading="lazy"><p class="svc-desc">Other agencies "manage ads." We engineer paid marketing engines run by senior operators and powered by our proprietary AI.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a><a class="svc-card" style="--accent:#10B981" href="/ai-search"><span class="svc-svc">Service II</span><div class="svc-name">AI <br class="svc-wbr">Search</div><img class="svc-emb" src="/engravings/lighthouse.png" alt="" loading="lazy"><p class="svc-desc">Your buyers stopped Googling and started asking AI what to buy. We make sure the answer is you, across ChatGPT, Perplexity, and Gemini.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a><a class="svc-card" style="--accent:#FE052C" href="/chatgpt-ads"><span class="svc-svc">Service III</span><div class="svc-name">ChatGPT <br class="svc-wbr">Ads</div><img class="svc-emb" src="/engravings/pigeon.png" alt="" loading="lazy"><p class="svc-desc">Buying decisions used to start on Google. Now they happen inside ChatGPT, and we make sure you're front and center.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a></div><div class="svc-row"><a class="svc-card" style="--accent:#FE05AF" href="/story-systems"><span class="svc-svc">Service IV</span><div class="svc-name">Story <br class="svc-wbr">Systems</div><img class="svc-emb" src="/engravings/quill.png" alt="" loading="lazy"><p class="svc-desc">Most tech companies can't explain why anyone should care about their product. We craft a story s
21o compelling prospects don't just understand you, they show up already sold.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a><a class="svc-card" style="--accent:#FD9905" href="/ad-creative"><span class="svc-svc">Service V</span><div class="svc-name">Ad <br class="svc-wbr">Creative</div><img class="svc-emb" src="/engravings/gtm-tools.png" alt="" loading="lazy"><p class="svc-desc">We pair human creative taste with AI production, test dozens of concepts against real spend, and scale the ones that prove they work.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a><a class="svc-card" style="--accent:#5B3FD6" href="/landing-pages"><span class="svc-svc">Service VI</span><div class="svc-name">Landing <br class="svc-wbr">Pages</div><img class="svc-emb" src="/engravings/landing.png" alt="" loading="lazy"><p class="svc-desc">We audit the page your ads point to and rebuild it around what actually converts - using data from the hundreds of pages we&rsquo;ve optimized.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">&#8599;</span></span></a></div></div><div class="svc-cta"><p class="svc-cta-line">Not sure which service fits? Let's figure it out together.</p><a class="cta cta-svc" href="/contact"><canvas class="cta-noise" width="200" height="52"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Let's talk</span></a></div></div></section><section class="model" id="model" data-theme="dark">    <div class="section-wrap"><div class="model-head"><span class="overline">
21Our Model</span><h2 class="display-head">The agency model was never built for startups, let alone for the AI era. Ours is.</h2><p class="model-lead" data-split-scroll>Senior startup-growth talent, a full-stack team, proprietary AI, and built-in distribution, brought together in one model the old agency never could.</p></div><h3 class="model-solve-title">How we compare.</h3><div class="cmp-wrap"><div class="cmp"><div class="cmp-hl" aria-hidden="true"></div><div class="cmp-cell cmp-corner"></div><div class="cmp-cell cmp-h cmp-dc-h"><img class="cmp-crown" src="/engravings/crown.png" alt="" aria-hidden="true"><span>Demand Curve</span></div><div class="cmp-cell cmp-h">Traditional Agency</div><div class="cmp-cell cmp-h">Freelancers</div><div class="cmp-cell cmp-h">In-house Hire</div><div class="cmp-cell cmp-h">AI Alone</div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Elite startup-growth talent</span><span class="cmp-sub">Senior operators who only do startups</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Full growth stack</span><span class="cmp-sub">All of growth, handled by one team</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Strategy + execution</span><span class="cmp-sub">We plan it and do the work</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Proprietary AI</span><span class="cmp-sub">Trained on 7,000+ startups, not generic AI</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Built-in distribution</span><span class="cmp-sub">Put in front of your buyers</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Cross-portfolio intelligence</span><span class="cmp-sub">Patterns from thousands of startups</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell cmp-row-label"><span class="cmp-feat">Proven at scale</span><span class="cmp-sub">7,000+ startups, 43 unicorns</span></div><div class="cmp-cell cmp-dc-cell"><span class="cmp-mark yes"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 12h12"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div><div class="cmp-cell"><span class="cmp-mark no"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"></path></svg></span></div></div></div><a class="model-cta" href="/about">Learn about our model <span class="arrow">&#8594;</span></a></div></section><section class="praise" data-theme="dark"><div class="section-wrap"><div class="pe-focal"><span class="pe-crest-clip"><img class="pe-crest" src="/engravings/endorse-crest.png" alt=""></span><span class="overline">Recognition</span><h2 class="display-head praise-head">Don&rsquo;t just take our word for it.</h2></div><!-- V17: themed columns - testimonials / recognition / results --><div class="pe-cols"><div class="pe-col"><figure class="pe-card pe-q-card"><blockquote class="pe-q">Demand Curve has trained many YC company founders and employees - and is the team we regularly recommend. Growth marketing expertise is a critical component of startup success.</blockquote><figcaption class="pe-by"><img src="/assets/testimonials/gustaf.jpg" alt="Gustaf Alstr&ouml;mer" loading="lazy"><span><b>Gustaf Alstr&ouml;mer</b><span class="pe-role">Partner, Y Combinator</span></span></figcaption></figure><figure class="pe-card pe-q-card"><blockquote class="pe-q">The Demand Curve team knows paid acquisition, conversion, landing pages, and a lot more very well. If you're lagging behind on your growth skills, let them teach you what you're missing.</blockquote><figcaption class="pe-by"><img src="/assets/testimonials/alex-kracov.jpg" alt="Alex Kracov" loading="lazy"><span><b>Alex Kracov</b><span class="pe-role">Head of Marketing, Lattice</span></span></figcaption></figure><figure class="pe-card pe-q-card"><blockquote class="pe-q">These are the people we go to for growth advice. They pointed out what we needed to change in our Facebook/Instagram strategy and landing pages - and it made the difference.</blockquote><figcaption class="pe-by"><img src="/assets/testimonials/brian-krall.jpg" alt="Brian Krall" loading="lazy"><span><b>Brian Krall</b><span class="pe-role">Lead Developer, Tovala (YC W16)</span></span></figcaption></figure></div><div class="pe-col"><div class="pe-card pe-cred"><span class="pe-kick">Press</span><img class="pe-logo w" src="/assets/logos/techcrunch.svg" alt="TechCrunch"><span class="pe-cl">We wrote TechCrunch's monthly growth column.</span></div><span class="pe-card pe-cred"><span class="pe-kick">Recognition</span><img class="pe-logo" src="/assets/logos/producthunt-wordmark.svg" alt="Product Hunt"><span class="pe-cl">A top-3 all-time growth guide</span></span><div class="pe-card pe-cred"><span class="pe-kick">Network</span><img class="pe-logo" src="/assets/logos/ycombinator.svg" alt="Y 
21Combinator"><span class="pe-cl">Regularly recommended by YC partners.</span></div><div class="pe-card pe-cred"><span class="pe-kick">Speaking</span><img class="pe-logo" src="/assets/logos/google.svg" alt="Google"><span class="pe-cl">We run growth talks for Google &amp; YC.</span></div></div><div class="pe-col"><div class="pe-card pe-win"><span class="pe-kick">Result</span><span class="pe-num">+800%</span><span class="pe-cat">MRR &middot; Consumer SaaS</span><img class="pe-winlogo" src="/assets/logos/doopoll.svg" alt="doopoll"></div><div class="pe-card pe-win"><span class="pe-kick">Result</span><span class="pe-num">+500%</span><span class="pe-cat">MAU &middot; B2B</span><img class="pe-winlogo" src="/assets/logos/astra.avif" alt="Astra"></div><div class="pe-card pe-win"><span class="pe-kick">Result</span><span class="pe-num">2&times;</span><span class="pe-cat">Conversions &middot; Ecommerce</span><img class="pe-winlogo" src="/assets/logos/3leaf.avif" alt="3 Leaf Tea"></div><a class="pe-card pe-cta" href="/contact"><span class="pe-cta-k">Want results like this?</span><span class="pe-cta-go">Let's talk <span class="arrow">&#8594;</span></span></a></div></div></div></section><div class="seam" style="--from:#171818; --to:#004AFF"></div><section class="dist" data-theme="blue">    <div class="section-wrap"><span class="overline">Distribution</span><div class="dist-bignum">1,000,000+</div><h2 class="display-head dist-head">We don't just build distribution channels. We are one.</h2><div class="dist-rule"><span class="ln"></span><span class="dot"></span><span class="ln"></span></div><p class="dist-body">Over the last decade, we've built the largest community of startup founders and growth operators in tech. When you work with Demand Curve, you get a trusted channel to the exact audience most startups spend years trying to reach.</p><div class="dist-stats"><div class="dist-stat"><span class="dist-stat-num">100K+</span><span class="dist-stat-label">Community members</span><p class="dist-stat-desc">Founders and growth operators.</p></div><div class="dist-stat"><span class="dist-stat-num">1M+</span><span class="dist-stat-label">Total reach</span><p class="dist-stat-desc">Across our media and content ecosystem.</p></div></div><div class="dist-cta-wrap"><a class="cta cta-dist" href="/sponsorships"><canvas class="cta-noise" width="200" height="52"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Explore partnerships</span></a></div></div></section><div class="seam" style="--from:#004AFF; --to:#ffffff"></div><section class="signalx" data-theme="light"><div class="sigx-field left" aria-hidden="true"></div><div class="sigx-field right" aria-hidden="true"></div><div class="signalx-inner"><span class="signalx-emblem" aria-hidden="true"></span><span class="signalx-over">Meet Signal</span><h2 class="signalx-h">Everyone has access to the same AI.<br>Our clients get Signal.</h2><p class="signalx-body">Most AI runs on the same public data as everyone else. Signal runs on our proprietary Growth Engine methodology, a decade of data no one else has from 7,000+ startups, and a community of 100,000+ operators sharing what&rsquo;s working right now.</p><a class="cta cta-signal" href="/about"><canvas class="cta-noise" width="200" height="54"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Learn more about Signal</span></a></div></section><section class="results" data-theme="light"><div class="results-head"><h2 class="results-title">Proof, not promises.</h2><p class="results-sub">Real results from the startups we’ve worked with - and what their founders say about it.</p></div><div class="hcs"><div class="section-wrap"><div class="hcs-shell"><!-- TABS --><div class="hcs-tabs" role="tablist" aria-label="Case studies"><button class="hcs-tab is-active" type="button" role="tab" id="hcs-tab-snitcher" aria-controls="hcs-panel-snitcher" aria-selected="true" data-cstab="snitcher"><img class="hcs-tab-logo" src="/assets/logos/cs/snitcher.png" alt="Snitcher" loading="lazy"><span class="hcs-tab-cat">Sales Tools</span></button><button class="hcs-tab" type="button" role="tab" id="hcs-tab-workos" aria-controls="hcs-panel-workos" aria-selected="false" data-cstab="workos"><img class="hcs-tab-logo" src="/assets/logos/cs/workos.png" alt="WorkOS" loading="lazy"><span class="hcs-tab-cat">Dev Tools</span></button><button class="hcs-tab" type="button" role="tab" id="hcs-tab-videogen" aria-controls="hcs-panel-videogen" aria-selected="false" data-cstab="videogen"><img class="hcs-tab-logo" src="/assets/logos/cs/videogen.svg" alt="Videogen" loading="lazy"><span class="hcs-tab-cat">AI Video</span></button><button class="hcs-tab" type="button" role="tab" id="hcs-tab-firmpilot" aria-controls="hcs-panel-firmpilot" aria-selected="false" data-cstab="firmpilot"><img class="hcs-tab-logo" src="/assets/logos/cs/firmpilot.svg" alt="FirmPilot" loading="lazy"><span class="hcs-tab-cat">LegalTech</span></button></div><!-- PANELS --><div class="hcs-stage"><!-- Snitcher --><div class="hcs-panel is-active" role="tabpanel" id="hcs-panel-snitcher" aria-labelledby="hcs-tab-snitcher" data-cspanel="snitcher"><div class="hcs-main"><span class="hcs-eyebrow">Sales Tools</span>
21<h3 class="hcs-name">Snitcher</h3><p class="hcs-desc">A B2B visitor-identification platform that reveals which companies visit your site before they ever fill out a form. 45,000+ users globally.</p><div class="hcs-stats"><div class="hcs-stat"><span class="hcs-stat-num">~4x</span><span class="hcs-stat-label">Revenue from paid in 12 months</span></div><div class="hcs-stat"><span class="hcs-stat-num">2 &rarr; 4</span><span class="hcs-stat-label">Active channels</span></div></div></div><div class="hcs-detail"><div class="hcs-block"><span class="hcs-k">The challenge</span><p>Running Google Ads at modest returns with no way to scale. A previous agency had left messy infrastructure - overlapping keywords, shared budgets cannibalizing campaigns, and only two channels live.</p></div><div class="hcs-block"><span class="hcs-k">What we did</span><ul class="hcs-list"><li>Paid across Google, Meta, Bing, and LinkedIn</li><li>Rebuilt the campaign architecture from scratch</li><li>Keyword + intent segmentation</li><li>New ad copy and retargeting</li><li>Channel expansion + platform recovery</li></ul></div><div class="hcs-block"><span class="hcs-k">Results</span><ul class="hcs-list hcs-list--win"><li>~4x increase in revenue from paid in 12 months</li><li>Expanded from 2 to 4 active channels</li><li>Hit the best-performing month in company history</li></ul></div></div></div><!-- WorkOS --><div class="hcs-panel" role="tabpanel" id="hcs-panel-workos" aria-labelledby="hcs-tab-workos" data-cspanel="workos" hidden><div class="hcs-main"><span class="hcs-eyebrow">Dev Tools</span><h3 class="hcs-name">WorkOS</h3><p class="hcs-desc">A developer platform for shipping enterprise features - SSO, directory sync, audit logs - fast. Backed by Lightspeed; used by Vercel and Copy.ai.</p><div class="hcs-stats"><div class="hcs-stat"><span class="hcs-stat-num">9x</span><span class="hcs-stat-label">Qualified leads from Google</span></div></div><blockquote class="hcs-quote">&ldquo;One of the best partner relationships we have had.&rdquo;</blockquote><p class="hcs-quote-attr">Head of Marketing, WorkOS</p></div><div class="hcs-detail"><div class="hcs-block"><span class="hcs-k">The challenge</span><p>Investing in Google Ads but generating near-zero qualified signups. Disorganized CRM, no visibility into lead qualification, and no feedback loop between ad spend and pipeline quality.</p></div><div class="hcs-block"><span class="hcs-k">What we did</span><ul class="hcs-list"><li>Google Ads strategy + structured experimentation</li><li>Full-funnel measurement with HubSpot</li><li>GTM + sales-process alignment</li><li>Lead-scoring framework</li></ul></div><div class="hcs-block"><span class="hcs-k">Results</span><ul class="hcs-list hcs-list--win"><li>9x increase in qualified lead flow from Google</li><li>
21Held strong ad efficiency across a multi-year engagement</li></ul></div></div></div><!-- Videogen --><div class="hcs-panel" role="tabpanel" id="hcs-panel-videogen" aria-labelledby="hcs-tab-videogen" data-cspanel="videogen" hidden><div class="hcs-main"><span class="hcs-eyebrow">AI Video &middot; YC-backed</span><h3 class="hcs-name">Videogen</h3><p class="hcs-desc">A YC-backed AI video platform that generates video at scale.</p><div class="hcs-stats"><div class="hcs-stat"><span class="hcs-stat-num">8x</span><span class="hcs-stat-label">Ad spend, scaled profitably</span></div><div class="hcs-stat"><span class="hcs-stat-num">$493k</span><span class="hcs-stat-label">Monthly spend in 90 days</span></div><div class="hcs-stat"><span class="hcs-stat-num">6,000+</span><span class="hcs-stat-label">New paying users</span></div></div></div><div class="hcs-detail"><div class="hcs-block"><span class="hcs-k">The challenge</span><p>Plateaued at ~$50k/month in ad spend. Every push to scale spiked CAC - branded and non-branded traffic were blended together, and there was no system for expanding into new audiences while holding efficiency.</p></div><div class="hcs-block"><span class="hcs-k">What we did</span><ul class="hcs-list"><li>Restructured campaigns into LTV tiers (high-LTV, scalable, test)</li><li>Switched Target ROAS to Target CPA to unlock volume</li><li>Added competitor campaigns (Runway, Sora intent)</li><li>Creative-testing system - 20% of spend always on fresh ads</li></ul></div><div class="hcs-block"><span class="hcs-k">Results</span><ul class="hcs-list hcs-list--win"><li>Scaled $62k to $493k/month in ad spend in 90 days, profitably</li><li>Held CAC within ~20% of baseline the whole way</li><li>Raised a round on the back of the growth</li></ul></div></div></div><!-- FirmPilot --><div class="hcs-panel" role="tabpanel" id="hcs-panel-firmpilot" aria-labelledby="hcs-tab-firmpilot" data-cspanel="firmpilot" hidden><div class="hcs-main"><span class="hcs-eyebrow">LegalTech &middot; venture-backed</span><h3 class="hcs-name">FirmPilot</h3><p class="hcs-desc">An AI marketing platform for law firms - backed by Thomson Reuters Ventures, HubSpot Ventures, and Blumberg Capital. High-ACV: $50-100K deals on 6-12 month contracts.</p><div class="hcs-stats"><div class="hcs-stat"><span class="hcs-stat-num">8x+</span><span class="hcs-stat-label">ROAS on ad spend</span></div><div class="hcs-stat"><span class="hcs-stat-num">0 &rarr; many</span><span class="hcs-stat-label">High-ACV deals / month</span></div></div></div><div class="hcs-detail"><div class="hcs-block"><span class="hcs-k">The challenge</span><p>Spending on paid acquisition but closing zero deals from it. Plenty of lead volume, but nothing connecting ad spend to pipeline - and no clarity on what was actually working.</p></div><div class="hcs-block"><span class="hcs-k">What we did</span><ul class="hcs-list"><li>Paid across Meta, Google, and LinkedIn</li><li>Redesigned lead forms + qualification</li><li>Real-time sales notification flow</li><li>ICP and audience refinement</li><li>Full-funnel measurement</li></ul></div><div class="hcs-block"><span class="hcs-k">Results</span><ul class="hcs-list hcs-list--win"><li>Went from zero closed deals on paid to multiple high-ACV deals every month</li><li>Roughly doubled ad spend while improving efficiency</li></ul></div></div></div></div></div></div></div><div class="results-cards" style="margin-top:0"><div class="rcards"><div class="rcards__track"><div class="rcards__group"><div class="rcard rcard--quote"><p class="rcard-quote">"Doing Demand Curve helps a lot to put the best tactics into action because it's so personalized. They really dig into every single word on our LP, ads, etc. to boost our growth."</p><p class="rcard-attr">&mdash; Daniel Dinh, @beinglong</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Started the Demand Curve growth marketing program a couple of months ago and it's the best thing I've done for my business so far. Learned so much in just a few months and probably saved myself years in trial and error."</p><p class="rcard-attr">&mdash; Elom Ayeboua, @elomaur</p></div><div class="rcard rcard--quote"><p class="rcard-quote">
21"This is a VERY GOOD teardown of @ahrefs homepage by @jynble from Demand Curve. I think we're going to make some changes to our homepage based on some of these recommendations."</p><p class="rcard-attr">&mdash; Tim Soulo, @timsoulo</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"If you're building out your marketing strategy, I'd highly recommend checking out Demand Curve's growth programs. They distill everything you need to know about paid ads, landing pages, and more, and guide you through every step of the way."</p><p class="rcard-attr">&mdash; Brian Maurer, @brianmaurer_</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Anyone new to digital ads needs to check out Demand Curve. Super helpful understanding which channels are relevant, learning to launch them, and then scaling them up."</p><p class="rcard-attr">&mdash; Matthew McLellan, @MattyMcLellan</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Just finished the Demand Curve program recently. They changed how I thought about creating effective content for SEO as well as how to tackle different paid channels. Would recommend anyone looking to grow their company reach out to them!"</p><p class="rcard-attr">&mdash; Harry Qi, @HarryQi6</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"I open and read every email that Demand Curve sends. The content is advanced and teaches something novel and useful in each issue."</p><p class="rcard-attr">&mdash; Kunal Mamtura, @kunversation</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Going through the Demand Curve program for the past few months has been one of the best decisions for my business. Incredible mentorship."</p><p class="rcard-attr">&mdash; Erik Korem, @ErikKorem</p></div></div><div class="rcards__group" aria-hidden="true"><div class="rcard rcard--quote"><p class="rcard-quote">"Doing Demand Curve helps a lot to put the best tactics into action because it's so personalized. They really dig into every single word on our LP, ads, etc. to boost our growth."</p><p class="rcard-attr">&mdash; Daniel Dinh, @beinglong</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Started the Demand Curve growth marketing program a couple of months ago and it's the best thing I've done for my business so far. Learned so much in just a few months and probably saved myself years in trial and error."</p><p class="rcard-attr">&mdash; Elom Ayeboua, @elomaur</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"This is a VERY GOOD teardown of @ahrefs homepage by @jynble from Demand Curve. I think we're going to make some changes to our homepage based on some of these recommendations."</p><p class="rcard-attr">&mdash; Tim Soulo, @timsoulo</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"If you're building out your marketing strategy, I'd highly recommend checking out Demand Curve's growth programs. They distill everything you need to know about paid ads, landing pages, and more, and guide you through every step of the way."</p><p class="rcard-attr">&mdash; Brian Maurer, @brianmaurer_</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Anyone new to digital ads needs to check out Demand Curve. Super helpful understanding which channels are relevant, learning to launch them, and then scaling them up."</p><p class="rcard-attr">&mdash; Matthew McLellan, @MattyMcLellan</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Just finished the Demand Curve program recently. They changed how I thought about creating effective content for SEO as well as how to tackle different paid channels. Would recommend anyone looking to grow their company reach out to them!"</p><p class="rcard-attr">&mdash; Harry Qi, @HarryQi6</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"I open and read every email that Demand Curve sends. The content is advanced and teaches something novel and useful in each issue."</p><p class="rcard-attr">&mdash; Kunal Mamtura, @kunversation</p></div><div class="rcard rcard--quote"><p class="rcard-quote">"Going through the Demand Curve program for the past few months has been one of the best decisions for my business. Incredible mentorship."</p><p class="rcard-attr">&mdash; Erik Korem, @ErikKorem</p></div></div></div></div></div></section>
21<script>
22  /* Case-study tabs. Same behavior as the /paid-marketing explorer; kept as its
23     own copy because that one lives in paid-marketing.astro, not a shared file. */
24  (function () {
25    var root = document.querySelector('.hcs');
26    if (!root) return;
27    var tabs = Array.prototype.slice.call(root.querySelectorAll('.hcs-tab'));
28    var panels = Array.prototype.slice.call(root.querySelectorAll('.hcs-panel'));
29    function select(slug) {
30      tabs.forEach(function (t) {
31        var on = t.getAttribute('data-cstab') === slug;
32        t.classList.toggle('is-active', on); t.setAttribute('aria-selected', on ? 'true' : 'false');
33      });
34      panels.forEach(function (p) {
35        var on = p.getAttribute('data-cspanel') === slug;
36        p.hidden = !on;
37        if (on) { p.classList.remove('is-active'); void p.offsetWidth; p.classList.add('is-active'); }
38        else p.classList.remove('is-active');
39      });
40    }
41    tabs.forEach(function (t, i) {
42      t.addEventListener('click', function () { select(t.getAttribute('data-cstab')); });
43      /* left/right arrows move between tabs, which is what a tablist should do
44         and costs nothing here. */
45      t.addEventListener('keydown', function (e) {
46        var d = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0;
47        if (!d) return;
48        e.preventDefault();
49        var n = tabs[(i + d + tabs.length) % tabs.length];
50        n.focus(); select(n.getAttribute('data-cstab'));
51      });
52    });
53  })();
54  </script>
54<section class="faq" data-theme="light"><div class="section-wrap faq-wrap"><div class="faq-intro"><span class="overline">FAQ</span><h2 class="display-head faq-head">The questions founders actually ask.</h2><p class="faq-sub">Everything teams usually ask before working with us. Still stuck? We&rsquo;re one conversation away.</p><a class="cta cta-svc faq-talk" href="/contact"><canvas class="cta-noise" width="200" height="52"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Let's talk</span></a></div><div class="faq-list"><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">You say you&rsquo;ve rebuilt the agency model. What&rsquo;s actually different?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Traditional agencies aren&rsquo;t built for startups. They&rsquo;re built for big clients and their own margin, which means an army of junior account managers, standardized playbooks, and bloated meeting cycles. Worse, they&rsquo;re built to sell, not deliver. You meet their polished executives during the sales process, hear all about the awards they&rsquo;ve won and how elite their team is, and sign. Then, unbeknownst to you, you&rsquo;re handed to a junior team, shielded behind an account manager who&rsquo;s really a salesperson in a strategist&rsquo;s clothing. Meanwhile startups sit at the bottom of the priority list while the senior people stay on the bigger accounts.</p><p>We flipped that model on its head. Everyone here is a senior growth expert, no juniors, no middlemen, not even in sales. The people you talk to from day one are the real deal. And our terms prove it: most agencies lock you into long contracts because it&rsquo;s the only way to keep clients they know they&rsquo;ll underdeliver for. We work month to month. We&rsquo;d rather earn your business every single month than trap you in a year of work we haven&rsquo;t earned yet.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">What makes you startup growth experts specifically?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Here&rsquo;s the dirty secret of our industry: growth at a big company isn&rsquo;t that hard. The machine already works, the budgets are huge, the data goes back years. It&rsquo;s mostly optimization, running playbooks someone else already wrote. But who wrote those playbooks to begin with? Inventing what works from scratch, with no machine and every dollar counting, is the hard part. That&rsquo;s why startup growth is so difficult, and why so few people are truly great at it. But those are the only people we hire.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">Everyone claims to use AI now. How is Signal different?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Most agencies are wrapping the same off-the-shelf tools everyone else has, trained on the same public data, so they get the same average outputs. Signal is our own AI, trained on a decade of data no one else has from 7,000+ startups, our Growth Engine methodology, and a community of 100,000+ operators sharing what&rsquo;s working directly from the front lines. It gives our strategists superpowers, helping them move faster and spot opportunities they&rsquo;d never spot alone, while the highest-leverage work, the strategy and the hard problems, stays firmly with our people.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">What do you mean by &ldquo;built-in distribution&rdquo;?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Any agency can manage your channels. But how many are a distribution channel themselves? We are. Our newsletter reaches 100,000+ founders and operators, and our broader media property, The Frontier, reaches over a million people a year. But the real value isn&rsquo;t the reach, it&rsquo;s the trust. We&rsquo;ve been one of the most trusted voices in startup growth for a decade, and the people in our world put weight on what we recommend. We can bring you into that world: a high-trust distribution channel that would take a decade to build yourself, and one that no other growth partner can offer.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">Who do you work with?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Our sweet spot is a startup entering or already in its growth stage, typically Series A through C, or a bootstrapped company producing at least seven figures in revenue with healthy margins. Usually the job is one of three: building your first scalable growth engine, breaking through a ceiling you&rsquo;ve hit, or layering new engines onto the one that got you here. On the vertical side, our bread and butter is consumer tech (software and hardware), B2B tech, and DTC. About the only company we&rsquo;re not built for is a pure enterprise sales model with no marketing-led motion.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">We&rsquo;re early-stage and still searching for product-market fit. Can you help?</span><span class="faq-ico" aria-hidden="true"></span></button><div class="faq-a"><div class="faq-a-inner"><p>Yes. We&rsquo;re startup people through and through, and we believe what most people call a product-market fit problem is usually a growth problem in disguise. When a startup fail
54s, the autopsy almost always points at the product. But the real issue is upstream: they never understood that growth has to be engineered into the DNA of the business, and that the product is only one piece of it. They bolted growth on as an afterthought, and it showed. They never got the right market in front of the product to even judge fit. They never told a story that made that market understand its true value. They never shaped the product around the channel that should have carried it, or built a revenue model that channel could support. Each of those is a growth decision, made too late or not at all. So yes, we work with early-stage startups, and when we say we architect growth into your DNA from the start, this is exactly what we mean.</p></div></div></div></div></div></section><div class="seam" style="--from:#ffffff; --to:#171818"></div><section class="outgrown outgrown--intro" data-theme="dark" style="background:#171818"><div class="section-wrap"><h2 class="outgrown-line display-head">The AI era moves fast. The Frontier keeps you ahead of the curve.</h2><p class="outgrown-sub">Join 100,000+ growth operators getting intel straight from the front lines.</p></div></section><section class="frontier" id="frontier" data-theme="dark"><div class="section-wrap"><div class="fr-meta"><span>Sheet 1/1</span><span>Demand Curve — The Frontier — Vol. VII · Edition 335</span><span>Proof: Final</span></div><div class="fr-frame"><span class="fr-cap tl"></span><span class="fr-cap tr"></span><span class="fr-cap bl"></span><span class="fr-cap br"></span><div class="fr-rule"><span class="ln"></span><span class="dot"></span><span class="dot"></span><span class="ln"></span></div><div class="fr-masthead"><div class="fr-kicker"><span>Est. 2020</span><span>✦</span><span>Published Weekly</span><span>✦</span><span>100,000+ Readers</span></div><h2 class="fr-title">The Frontier</h2></div><div class="fr-divider"><span class="ln"></span><span>✦</span><span class="ln"></span></div><div class="fr-ticker"><div class="fr-ticker-track"><span>■ #348 — How I got 900k+ impressions from just 10 social posts.&nbsp;&nbsp;|&nbsp;&nbsp;#347 — The visuals that belong on your landing page, how to tell whether your differentiator will last, and why pricing low can leave you unable to afford customers.&nbsp;&nbsp;|&nbsp;&nbsp;#346 — Trade a trial extension for a review, spot where AI video crosses the line, and turn discounts into credits&nbsp;&nbsp;|&nbsp;&nbsp;#345 — Avoid shrinkflation, what to do when building in public stops working, and how to make your product a ritual.&nbsp;&nbsp;|&nbsp;&nbsp;#344 — How to increase desire, why Bezos picked books, exclude your refunders.&nbsp;&nbsp;|&nbsp;&nbsp;#343 — Unoptimized marketing, onboarding friction, and AI search&nbsp;&nbsp;|&nbsp;&nbsp;</span><span aria-hidden="true">■ #348 — How I got 900k+ impressions from just 10 social posts.&nbsp;&nbsp;|&nbsp;&nbsp;#347 — The visuals that belong on your landing page, how to tell whether your differentiator will last, and why pricing low can leave you unable to afford customers.&nbsp;&nbsp;|&nbsp;&nbsp;#346 — Trade a trial extension for a review, spot where AI video crosses the line, and turn discounts into credits&nbsp;&nbsp;|&nbsp;&nbsp;#345 — Avoid shrinkflation, what to do when building in public stops working, and how to make your product a ritual.&nbsp;&nbsp;|&nbsp;&nbsp;#344 — How to increase desire, why Bezos picked books, exclude your refunders.&nbsp;&nbsp;|&nbsp;&nbsp;#343 — Unoptimized marketing, onboarding friction, and AI search&nbsp;&nbsp;|&nbsp;&nbsp;</span></div></div><div class="fr-grid"><div class="fr-lead"><span class="fr-tag">Most Recent Edition</span><h3><a href="/newsletters/growth-newsletter-348">How I got 900k+ impressions from just 10 social posts.</a></h3><p class="fr-lead-desc">Greetings loyal readers, If you&#x27;ve been reading for a while, you&#x27;ll recognize Kevin DePopas. He led growth for Demand Curve in 2025 and owned this newsletter through that…</p><div class="fr-subgrid"><article><div class="fr-sub-meta">#347 · Sep 2026</div><h4><a href="/newsletters/growth-newsletter-347">
54The visuals that belong on your landing page, how to tell whether your differentiator will last, and why pricing low can leave you unable to afford customers.</a></h4><span class="fr-read">Read edition &#8594;</span></article><article><div class="fr-sub-meta">#346 · Sep 2026</div><h4><a href="/newsletters/growth-newsletter-346">Trade a trial extension for a review, spot where AI video crosses the line, and turn discounts into credits</a></h4><span class="fr-read">Read edition &#8594;</span></article></div><div class="fr-list"><a class="fr-list-item" href="/newsletters/growth-newsletter-345"><span class="li-l"><span class="li-num">#345</span><span class="li-title">Avoid shrinkflation, what to do when building in public stops working, and how to make your product a ritual.</span></span><span class="li-tag">Aug 2026</span></a><a class="fr-list-item" href="/newsletters/growth-newsletter-344"><span class="li-l"><span class="li-num">#344</span><span class="li-title">How to increase desire, why Bezos picked books, exclude your refunders.</span></span><span class="li-tag">Aug 2026</span></a><a class="fr-list-item" href="/newsletters/growth-newsletter-343"><span class="li-l"><span class="li-num">#343</span><span class="li-title">Unoptimized marketing, onboarding friction, and AI search</span></span><span class="li-tag">Aug 2026</span></a><a class="fr-list-item" href="/newsletters/growth-newsletter-342"><span class="li-l"><span class="li-num">#342</span><span class="li-title">We&#x27;ve got some updates</span></span><span class="li-tag">Aug 2026</span></a><a class="fr-list-item" href="/newsletters/growth-newsletter-341"><span class="li-l"><span class="li-num">#341</span><span class="li-title">How breakout companies actually pull away</span></span><span class="li-tag">Jul 2026</span></a></div></div><div class="fr-sub"><h3>Never miss an edition</h3><p class="fr-sub-lead">Growth systems, tactics, and insights. Delivered from the frontier every week.</p><form class="fr-form" onsubmit="return false"><input type="email" placeholder="[email protected]"><button class="fr-subscribe" type="submit">Subscribe — Free</button></form><p class="fr-fine">No spam. Unsubscribe anytime.</p><div class="fr-stats"><div class="fr-stat"><span class="s-label">Subscribers</span><span class="s-val">100K+</span></div><div class="fr-stat"><span class="s-label">Editions</span><span class="s-val">348</span></div><div class="fr-stat"><span class="s-label">Companies</span><span class="s-val">7,000+</span></div><div class="fr-stat"><span class="s-label">Cadence</span><span class="s-val">Weekly</span></div></div><div class="fr-quote"><p>"The Demand Curve newsletter has to be one of our team's favorites - if you aren't already subscribed, we highly recommend it."</p><div class="q-attr">— Safely Finance, @SafelyFinance</div></div></div></div><div class="fr-rule bottom"><span class="ln"></span><span class="dot"></span><span class="dot"></span><span class="ln"></span></div></div><div class="fr-meta bottom"><span>Trim line</span><span>© Demand Curve 2026 · All rights reserved</span><span>Bleed: 3mm</span></div><div class="fr-nixie-wrap"><div class="fr-nixie"><span class="fr-mark tl" aria-hidden="true"></span><span class="fr-mark tr" aria-hidden="true"></span><span class="fr-mark bl" aria-hidden="true"></span><span class="fr-mark br" aria-hidden="true"></span><span class="fr-nixie-kicker">The Open Library</span><div class="fr-nixie-row" data-nixie="100000" role="img" aria-label="100,000 growth operators subscribed"></div><span class="fr-nixie-unit">Growth operators subscribed</span>
54<p class="fr-nixie-title">The Frontier is our open library of growth frameworks, playbooks, and research - trusted by 100,000+ operators.</p><span class="fr-cta-frame"><a class="fr-scroll-cta" href="/frontier"><span class="brk" aria-hidden="true"><i class="tl"></i><i class="tr"></i><i class="bl"></i><i class="br"></i></span><span class="orn" aria-hidden="true">&#10022;</span>Explore the full library<span class="orn" aria-hidden="true">&#10022;</span></a></span></div></div></div></section><section class="finale" data-theme="dark"><canvas class="finale-warp" aria-hidden="true"></canvas><div class="section-wrap"><img class="finale-emblem" src="/engravings/finale-emblem.png" alt="" aria-hidden="true" loading="lazy"><span class="overline finale-eyebrow">Ready when you are</span><h2 class="finale-head display-head">Let&rsquo;s build your growth engine.</h2><a class="cta cta-svc cta-finale" href="/contact"><canvas class="cta-noise" width="200" height="52"></canvas><span class="cta-corners"><i class="c tl"></i><i class="c tr"></i><i class="c bl"></i><i class="c br"></i></span><span class="cta-label">Let's talk</span></a></div></section>
54<script>
55    /* -------- story: scroll-driven word-by-word highlight -------- */
56  (function () {
57    var section = document.querySelector('.story');
58    var paras = document.querySelectorAll('.story-para[data-split]');
59    if (!section || !paras.length) return;
60
61    // split every paragraph into word spans
62    paras.forEach(function (p) {
63      var words = p.textContent.trim().split(/\s+/);
64      p.innerHTML = words.map(function (w) {
65        var safe = w.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
66        return '<span class="w">' + safe + '</span>';
67      }).join(' ');
68    });
69    // collect spans across ALL paragraphs in reading order -> one continuous reveal
70    var spans = section.querySelectorAll('.w');
71
72    function clamp(v) { return Math.max(0, Math.min(1, v)); }
73
74    var FEATHER = 8;       // how many words are mid-fade at once
75    var HEAD_START = 4;    // words already lit when the section first pins
76
77    var ticking = false;
78    function render() {
79      ticking = false;
80      // Begin revealing while the section is still scrolling IN (top still below
81      // the pin point), then continue through the pinned scroll.
82      var vh = window.innerHeight;
83      var lead = vh * 0.6;      // start when the section top is 60% down the viewport
84      var scrollable = section.offsetHeight - vh;
85      var top = section.getBoundingClientRect().top;
86      var p = clamp((vh * 0.85 - section.getBoundingClientRect().top) / (section.offsetHeight + vh * 0.45));
87      var head = HEAD_START + p * (spans.length + FEATHER);
88      for (var i = 0; i < spans.length; i++) {
89        var t = clamp((head - i) / FEATHER);
90        spans[i].style.opacity = (0.2 + 0.8 * t).toFixed(3);
91      }
92    }
93    function onScroll() {
94      if (!ticking) { ticking = true; window.requestAnimationFrame(render); }
95    }
96    window.addEventListener('scroll', onScroll, { passive: true });
97    window.addEventListener('resize', onScroll);
98    render();
99  })();
100
101  /* -------- model lead: scroll-driven letter-by-letter highlight (non-pinned) -------- */
102  (function () {
103    var el = document.querySelector('.model-lead[data-split-scroll]');
104    if (!el) return;
105    var text = el.textContent;
106    var html = '';
107    for (var c = 0; c < text.length; c++) {
108      var ch = text[c];
109      if (ch === ' ') { html += ' '; continue; }
110      var safe = ch.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
111      html += '<span class="ml">' + safe + '</span>';
112    }
113    el.innerHTML = html;
114    var spans = el.querySelectorAll('.ml');
115    var N = spans.length;
116    function clamp(v) { return Math.max(0, Math.min(1, v)); }
117    var FEATHER = 6;            // how many letters are mid-fade at once
118    var ticking = false;
119    function render() {
120      ticking = false;
121      var vh = window.innerHeight;
122      var r = el.getBoundingClientRect();
123      var startY = vh * 0.98;   // begin as soon as it enters from the bottom
124      var span = (startY - vh * 0.5) + r.height;   // finish by ~mid-screen
125      var p = clamp((startY - r.top) / span);
126      var head = p * (N + FEATHER);
127      for (var i = 0; i < N; i++) {
128        var t = clamp((head - i) / FEATHER);
129        spans[i].style.opacity = (0.22 + 0.78 * t).toFixed(3);
130      }
131    }
132    function onScroll() { if (!ticking) { ticking = true; window.requestAnimationFrame(render); } }
133    window.addEventListener('scroll', onScroll, { passive: true });
134    window.addEventListener('resize', onScroll);
135    render();
136  })();
137
138
139  /* -------- Meet Signal: pinned, letter-by-letter highlight (like the story) -------- */
140  (function () {
141    var section = document.querySelector('.signal');
142    var paras = document.querySelectorAll('.signal-para[data-signal]');
143    if (!section || !paras.length) return;
144    paras.forEach(function (p) {
145      var html = '';
146      // Array.from splits by code points so emoji (👋 = a surrogate pair) stay intact
147      Array.from(p.textContent).forEach(function (ch) {
148        if (ch === ' ') { html += ' '; return; }
149        var safe = ch.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
150        html += '<span class="signal-l">' + safe + '</span>';
151      });
152      p.innerHTML = html;
153    });
154    var spans = section.querySelectorAll('.signal-l');
155    var N = spans.length;
156    function clamp(v) { return Math.max(0, Math.min(1, v)); }
157    var FEATHER = 18, HEAD_START = 6;
158    var ticking = false;
159    function render() {
160      ticking = false;
161      var vh = window.innerHeight;
162      var lead = vh * 0.45;     // begin revealing before it fully pins
163      var scrollable = section.offsetHeight - vh;
164      var p = clamp((vh * 0.85 - section.getBoundingClientRect().top) / (section.offsetHeight + vh * 0.45));
165      var head = HEAD_START + p * (N + FEATHER);
166      for (var i = 0; i < N; i++) {
167        var t = clamp((head - i) / FEATHER);
168        spans[i].style.opacity = (0.16 + 0.84 * t).toFixed(3);
169      }
170    }
171    function onScroll() { if (!ticking) { ticking = true; window.requestAnimationFrame(render); } }
172    window.addEventListener('scroll', onScroll, { passive: true });
173    window.addEventListener('resize', onScroll);
174    render();
175  })();
176
177  /* -------- Signal side blocks: animated interference field (scroll + time) -------- */
178  (function () {
179    var section = document.querySelector('.signal');
180    var decos = document.querySelectorAll('.signal-deco');
181    if (!section || !decos.length) return;
182    var MOBILE = window.matchMedia('(max-width: 768px)').matches;
183    var COLS = MOBILE ? 18 : 6, ROWS = MOBILE ? 4 : 26, maxO = (COLS - 1) + (ROWS - 1);   // mobile: one short horizontal strip, fewer squares
184    decos.forEach(function (d) {
185      d.innerHTML = '';
186      for (var i = 0; i < COLS * ROWS; i++) {
187        var c = document.createElement('span'); c.className = 'signal-cell'; d.appendChild(c);
188      }
189    });
190    function clamp(v) { return Math.max(0, Math.min(1, v)); }
191    // greyscale ramp (homepage) — squares switch among these as the wave moves
192    var BLUES = ['#171818', '#33353a', '#4d5058', '#6a6e77', '#26282d', '#3f4248', '#1c1e22'];
193    // per-cell weights (clustered sine + jitter) -> ragged/organic shape, not a solid block
194    var weights = [];
195    for (var wi = 0; wi < COLS * ROWS; wi++) {
196      var wc = wi % COLS, wr = (wi / COLS) | 0;
197      var base = 0.5 + 0.5 * Math.sin(wc * 1.3 + wr * 0.55) * Math.cos(wr * 0.42 - wc * 0.8);
198      weights[wi] = clamp(base * 0.65 + Math.random() * 0.6);
199    }
200    var ticking = false;
201    function render() {
202      ticking = false;
203      var vh = window.innerHeight;
204      var lead = vh * 0.45;
205      var scrollable = section.offsetHeight - vh;
206      var p = clamp((vh * 0.85 - section.getBoundingClientRect().top) / (section.offsetHeight + vh * 0.45));
207      var head = p * 1.3;   // wavefront sweeps past the grid as you scroll
208      decos.forEach(function (d, di) {
209        var cells = d.children;
210        for (var i = 0; i < cells.length; i++) {
211          var col = i % COLS, row = (i / COLS) | 0;
212          var c = di === 1 ? (COLS - 1 - col) : col;
213          var o = (c + row) / maxO;
214          var bandv = Math.max(0, 1 - Math.abs(o - head) / 0.26);
215          var op = bandv * weights[c + row * COLS] * 0.55;
216          cells[i].style.opacity = op.toFixed(3);
217          cells[i].style.background = BLUES[(c + row + ((head * 9) | 0) + di) % BLUES.length];
218        }
219      });
220    }
221    function onScroll() { if (!ticking) { ticking = true; window.requestAnimationFrame(render); } }
222    window.addEventListener('scroll', onScroll, { passive: true });
223    window.addEventListener('resize', onScroll);
224    render();
225  })();
226
227  /* -------- infinite nested-outline "Demand Curve" -------- */
228  (function () {
229    var wrap = document.getElementById('inf-dc');
230    if (!wrap) return;
231    var section = document.querySelector('.ascii-banner');
232    var N = 14, texts = [];
233    for (var i = 0; i < N; i++) {
234      var t = document.createElement('span');
235      t.className = 'inf-text';
236      t.textContent = 'Demand Curve';
237      wrap.appendChild(t);
238      texts.push(t);
239    }
240    // p: 0 = tiny/far, 1 = huge/near. Grows toward you, fades in then out, loops.
241    function place(t, p) {
242      var s = 0.12 * Math.pow(34, p);
243      var op = Math.max(0, Math.min(1, p / 0.14)) * Math.max(0, Math.min(1, (1 - p) / 0.3));
244      t.style.transform = 'translate(-50%, -50%) scale(' + s.toFixed(3) + ')';
245      t.style.opacity = op.toFixed(3);
246    }
247    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
248      texts.forEach(function (t, i) { place(t, 0.5); if (i) t.style.opacity = '0'; });
249      return;
250    }
251    var active = true;
252    if ('IntersectionObserver' in window) {
253      var io = new IntersectionObserver(function (es) { active = es[0].isIntersecting; }, { threshold: 0 });
254      if (section) io.observe(section);
255    }
256    var time = 0;
257    function loop() {
258      window.requestAnimationFrame(loop);
259      if (!active) return;
260      time += 0.0032;   // forward-zoom speed
261      for (var i = 0; i < N; i++) place(texts[i], (time + i / N) % 1);
262    }
263    loop();
264  })();
265
266  /* -------- Frontier scroll: unroll is DRIVEN by scroll position --------
267     Opens as it rises into view, rolls back shut as you scroll away. */
268  (function () {
269    var el = document.querySelector('.fr-scroll');
270    if (!el) return;
271    var rollL = el.querySelector('.fr-roll--l');
272    var rollR = el.querySelector('.fr-roll--r');
273    var sheet = el.querySelector('.fr-sheet');
274    var inner = el.querySelector('.fr-scroll-inner');
275    if (!rollL || !rollR || !sheet || !inner) return;
276    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;   // stays open, no scrubbing
277
278    function clamp(v) { return Math.max(0, Math.min(1, v)); }
279    function smooth(p) { return p * p * (3 - 2 * p); }   // ease the travel
280
281    var ticking = false;
282    function render() {
283      ticking = false;
284      var vh = window.innerHeight;
285      var r = el.getBoundingClientRect();
286      // begin opening as the scroll enters from the bottom; fully open by ~mid-screen
287      var p = smooth(clamp((vh * 0.94 - r.top) / (vh * 0.46)));
288      var w = el.clientWidth;
289      var rw = rollL.offsetWidth || 36;
290      var lFrom = w / 2 - rw, lTo = -0.4 * rw;
291      var rFrom = w / 2, rTo = w - 0.6 * rw;
292      rollL.style.left = (lFrom + (lTo - lFrom) * p) + 'px';
293      rollR.style.left = (rFrom + (rTo - rFrom) * p) + 'px';
294      var x = Math.max(0, (w / 2 - rw * 0.6) * (1 - p));
295      sheet.style.clipPath = 'inset(-44px ' + x + 'px -44px ' + x + 'px)';
296      var o = clamp((p - 0.5) / 0.5);
297      inner.style.opacity = o.toFixed(3);
298      inner.style.transform = 'translateY(' + (6 * (1 - o)).toFixed(1) + 'px)';
299    }
300    function onScroll() { if (!ticking) { ticking = true; window.requestAnimationFrame(render); } }
301    window.addEventListener('scroll', onScroll, { passive: true });
302    window.addEventListener('resize', onScroll);
303    render();
304  })();
305  </script>
305<script type="module">
306  (async () => {
307    var banner = document.querySelector('.ascii-banner');
308    var canvas = document.getElementById('pb-canvas');
309    var fx = document.getElementById('bigmark-fx');
310    if (!banner || !canvas || !fx) return;
311
312    // Capability gate: the live WebGL wordmark is a desktop-only flourish.
313    // Small screens, low-power devices, and reduce-motion users keep the fast
314    // static "Demand Curve" wordmark — this is what fixes the mobile score.
315    var small  = !window.matchMedia('(min-width: 769px)').matches;
316    var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
317    var lowMem = (navigator.deviceMemory || 8) < 4;        // < 4GB RAM
318    var lowCpu = (navigator.hardwareConcurrency || 8) < 4; // < 4 CPU cores
319    if (small || reduce || lowMem || lowCpu) return;
320
321    try {
322      var gl = document.createElement('canvas').getContext('webgl2') || document.createElement('canvas').getContext('webgl');
323      if (!gl) return;
324    } catch (e) { return; }
325
326    // Load LATER: wait until the page has painted and the browser is idle, so
327    // downloading Three.js + running the effect never blocks first paint / LCP.
328    var start = function () {
329      import('/pb.js?v=da880e2c').then(function (mod) {
330        banner.classList.add('fx-on');                  // reveal canvas FIRST so it has real layout size
331        return mod.initWordmark({ canvas: canvas, container: fx, text: 'Demand Curve' });
332      }).catch(function () { banner.classList.remove('fx-on'); });  // fall back to the static wordmark
333    };
334    if ('requestIdleCallback' in window) requestIdleCallback(start, { timeout: 3000 });
335    else window.addEventListener('load', function () { setTimeout(start, 300); });
336  })();
337  </script>
337<div class="cs-modal cs-modal--light" id="csModal" aria-hidden="true"><div class="cs-scrim" data-cs-close></div><div class="cs-card" role="dialog" aria-modal="true" aria-label="Case study"><button class="cs-close" type="button" data-cs-close aria-label="Close">&times;</button><div class="cs-content"></div></div></div>
337<script>
338  (function () {
339    var CASES = {
340      videogen: {
341        cat: 'AI Video · YC-backed', name: 'Videogen',
342        desc: 'A YC-backed AI video platform that generates video at scale.',
343        challenge: 'Plateaued at ~$50k/month in ad spend. Every push to scale spiked CAC - branded and non-branded traffic were blended together, and there was no system for expanding into new audiences while holding efficiency.',
344        did: ['Restructured campaigns into LTV tiers (high-LTV, scalable, test)', 'Switched Target ROAS to Target CPA to unlock volume', 'Added competitor campaigns (Runway, Sora intent)', 'Creative-testing system - 20% of spend always on fresh ads'],
345        stats: [{ n: '8x', l: 'ad spend, profitably' }, { n: '$493k', l: 'monthly spend in 90 days' }, { n: '6,000+', l: 'new paying users' }],
346        results: ['Scaled $62k to $493k/month in ad spend in 90 days, profitably', 'Held CAC within ~20% of baseline the whole way', 'Raised a round on the back of the growth']
347      },
348      firmpilot: {
349        cat: 'LegalTech · venture-backed', name: 'FirmPilot',
350        desc: 'An AI marketing platform for law firms - backed by Thomson Reuters Ventures, HubSpot Ventures, and Blumberg Capital. High-ACV: $50-100K deals on 6-12 month contracts.',
351        challenge: 'Spending on paid acquisition but closing zero deals from it. Plenty of lead volume, but nothing connecting ad spend to pipeline - and no clarity on what was actually working.',
352        did: ['Paid across Meta, Google, and LinkedIn', 'Redesigned lead forms + qualification', 'Real-time sales notification flow', 'ICP and audience refinement', 'Full-funnel measurement'],
353        stats: [{ n: '8x+', l: 'ROAS on ad spend' }, { n: '0 → many', l: 'high-ACV deals / month' }],
354        results: ['Went from zero closed deals on paid to multiple high-ACV deals every month', 'Roughly doubled ad spend while improving efficiency', 'Raised from Thomson Reuters after a year-long partnership']
355      },
356      snitcher: {
357        cat: 'Sales Tools', name: 'Snitcher',
358        desc: 'A B2B visitor-identification platform that reveals which companies visit your site before they ever fill out a form. 45,000+ users globally.',
359        challenge: 'Running Google Ads at modest returns with no way to scale. A previous agency had left messy infrastructure - overlapping keywords, shared budgets cannibalizing campaigns, and only two channels live.',
360        did: ['Paid across Google, Meta, Bing, and LinkedIn', 'Rebuilt the campaign architecture', 'Keyword + intent segmentation', 'New ad copy and retargeting', 'Channel expansion + platform recovery'],
361        stats: [{ n: '~4x', l: 'revenue from paid (12 mo)' }, { n: '2 → 4', l: 'active channels' }],
362        results: ['~4x increase in revenue from paid in 12 months', 'Expanded from 2 to 4 channels', 'Hit the best-performing month in company history']
363      },
364      workos: {
365        cat: 'Dev Tools', name: 'WorkOS',
366        desc: 'A developer platform for shipping enterprise features - SSO, directory sync, audit logs - fast. Backed by Lightspeed; used by Vercel and Copy.ai.',
367        challenge: 'Investing in Google Ads but generating near-zero qualified signups. Disorganized CRM, no visibility into lead qualification, and no feedback loop between ad spend and pipeline quality.',
368        did: ['Google Ads strategy + experimentation', 'Full-funnel measurement with HubSpot', 'GTM + sales-process alignment', 'Lead-scoring framework'],
369        stats: [{ n: '9x', l: 'qualified leads from Google' }],
370        results: ['9x increase in qualified lead flow from Google', 'Held strong ad efficie
370ncy across a multi-year engagement'],
371        quote: 'One of the best partner relationships we have had.', quoteAttr: 'Head of Marketing, WorkOS'
372      }
373    };
374    var modal = document.getElementById('csModal');
375    if (!modal) return;
376    var content = modal.querySelector('.cs-content');
377    var card = modal.querySelector('.cs-card');
378    var current = null;
379    function esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
380    function render(c) {
381      var h = '<span class="cs-eyebrow">Case study · ' + esc(c.cat) + '</span>';
382      h += '<h3 class="cs-name">' + esc(c.name) + '</h3>';
383      h += '<p class="cs-desc">' + esc(c.desc) + '</p>';
384      if (c.stats) { h += '<div class="cs-statbar">'; c.stats.forEach(function (s) { h += '<div class="cs-stat"><span class="cs-stat-num">' + esc(s.n) + '</span><span class="cs-stat-label">' + esc(s.l) + '</span></div>'; }); h += '</div>'; }
385      h += '<span class="cs-h">The challenge</span><p class="cs-p">' + esc(c.challenge) + '</p>';
386      h += '<span class="cs-h">What we did</span><ul class="cs-list">' + c.did.map(function (d) { return '<li>' + esc(d) + '</li>'; }).join('') + '</ul>';
387      h += '<span class="cs-h">Results</span><ul class="cs-results">' + c.results.map(function (r) { return '<li>' + esc(r) + '</li>'; }).join('') + '</ul>';
388      if (c.quote) { h += '<p class="cs-quote">"' + esc(c.quote) + '"</p><p class="cs-quote-attr">' + esc(c.quoteAttr) + '</p>'; }
389      return h;
390    }
391    function open(slug) {
392      var c = CASES[slug]; if (!c || current === slug) return;
393      current = slug; content.innerHTML = render(c);
394      modal.classList.add('is-open'); modal.setAttribute('aria-hidden', 'false'); card.scrollTop = 0;
395    }
396    function close() { modal.classList.remove('is-open'); modal.setAttribute('aria-hidden', 'true'); current = null; }
397    document.addEventListener('click', function (e) {
398      var t = e.target.closest && e.target.closest('.cs-link');
399      if (t) { e.preventDefault(); open(t.getAttribute('data-cs')); return; }
400      if (e.target.closest('[data-cs-close]')) close();
401    });
402    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
403  })();
404  </script>
404<script>
405  /* Homepage newsletter form -> Kit (/api/subscribe). */
406  (function () {
407    var form = document.querySelector('.fr-sub .fr-form');
408    if (!form) return;
409    var EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
410    form.addEventListener('submit', function (e) {
411      e.preventDefault();
412      var input = form.querySelector('input[type="email"]');
413      var btn = form.querySelector('button');
414      var email = ((input && input.value) || '').trim();
415      if (!EMAIL.test(email)) { if (input) { input.focus(); input.style.borderColor = '#c0392b'; } return; }
416      var orig = btn.textContent; btn.disabled = true; btn.textContent = 'Subscribing…';
417      (function(){ var __dca = window.DCA ? window.DCA.payload() : {}; if (window.DCA) window.DCA.track('Subscribe – FE', { event_id: __dca.event_id }); return fetch('/api/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(Object.assign({}, __dca, { email: email, join: true })) }); })()
418        .then(function (r) {
419          if (r.status === 400) { btn.disabled = false; btn.textContent = orig; if (input) { input.focus(); input.style.borderColor = '#c0392b'; } return; }
420          if (!r.ok) throw new Error('status ' + r.status);
421          return r.json().catch(function(){ return {}; }).then(function (j) {
422            if (j && j.otpSent) { window.location.href = '/check-email?email=' + encodeURIComponent(email); return; }
423            form.style.display='none'; if(!form.nextElementSibling||!form.nextElementSibling.classList.contains('fr-subok')){ form.insertAdjacentHTML('afterend', '<p class="fr-subok" style="font-size:14px;margin-top:10px;font-weight:500;opacity:.92">You\'re subscribed. Welcome to The Frontier.</p>'); }
424          });
425        })
426        .catch(function () {
427          btn.disabled = false; btn.textContent = orig;
428          if (!form.nextElementSibling || !form.nextElementSibling.classList.contains('fr-suberr')) {
429            form.insertAdjacentHTML('afterend', '<p class="fr-suberr" style="color:#ffd2c2;font-size:13px;margin-top:8px">Hmm - that didn\'t go through. Please try again in a moment.</p>');
430          }
431        });
432    });
433  })();
434  </script>
434<script>
435  /* Who-it's-for: reveal the qualifier cells when the section scrolls into view */
436  (function () {
437    var wif = document.querySelector('.wif'); if (!wif) return;
438    if (!('IntersectionObserver' in window)) { wif.classList.add('in'); return; }
439    var io = new IntersectionObserver(function (es) {
440      es.forEach(function (e) { if (e.isIntersecting) { wif.classList.add('in'); io.disconnect(); } });
441    }, { threshold: 0.2 });
442    io.observe(wif);
443  })();
444  </script>
444<script>
445  /* How-we-compare: stamp the Demand Curve checks in one-by-one on scroll (cmp check-in) */
446  (function () {
447    var cmp = document.querySelector('.cmp'); if (!cmp) return;
448    var marks = cmp.querySelectorAll('.cmp-dc-cell .cmp-mark');
449    marks.forEach(function (el, i) { el.style.transitionDelay = (0.12 + i * 0.1) + 's'; });
450    if (!('IntersectionObserver' in window)) { cmp.classList.add('in'); return; }
451    var io = new IntersectionObserver(function (es) { es.forEach(function (e) { if (e.isIntersecting) { cmp.classList.add('in'); io.disconnect(); } }); }, { threshold: 0.25 });
452    io.observe(cmp);
453  })();
454  </script>
454<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js" integrity="sha384-g4NTh/Iv5PPU4xPyhEWqPcwtNXOvdaDI8LLnyYfyNZOjKJeYQyjzQ9X5275eBjpt" crossorigin="anonymous"></script>
454<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js" integrity="sha384-Z3REaz79l2IaAZqJsSABtTbhjgOUYyV3p90XNnAPCSHg3EMTz1fouunq9WZRtj3d" crossorigin="anonymous"></script>
454<script src="charreveal.js?v=mob1"></script>
454<script src="/faq.js" defer></script>
454<script src="/signal.js" defer></script>
454<script>
455  (function () {
456    var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
457    document.querySelectorAll('[data-nixie]').forEach(function (row) {
458      var raw = +row.getAttribute('data-nixie');
459      var str = raw.toLocaleString('en-US');           // "110,000"
460      var tubes = [];
461      Array.prototype.forEach.call(str, function (ch) {
462        if (ch === ',') {
463          var c = document.createElement('span');
464          c.className = 'fr-nixie-tube comma';
465          c.innerHTML = '<span>,</span>';
466          row.appendChild(c);
467          return;
468        }
469        var w = document.createElement('span');
470        w.className = 'fr-nixie-tube';
471        var s = document.createElement('span');
472        s.textContent = '0';
473        w.appendChild(s);
474        row.appendChild(w);
475        tubes.push(s);
476      });
477      var digits = str.replace(/,/g, '').length, seen = false;
478      function paint(n) {
479        var ds = String(n).padStart(digits, '0');
480        for (var i = 0; i < tubes.length; i++) tubes[i].textContent = ds[i] || '0';
481      }
482      function flicker() {
483        if (reduce) return;
484        setInterval(function () {
485          var tube = tubes[Math.floor(Math.random() * tubes.length)].parentNode;
486          tube.style.opacity = '0.4';
487          setTimeout(function () { tube.style.opacity = '1'; }, 90);
488        }, 2600);
489      }
490      new IntersectionObserver(function (es) {
491        es.forEach(function (e) {
492          if (!e.isIntersecting || seen) return;
493          seen = true;
494          if (reduce) { paint(raw); return; }
495          var st = performance.now();
496          (function tick(now) {
497            var p = Math.min(1, (now - st) / 1600), eased = 1 - Math.pow(1 - p, 3);
498            paint(Math.round(raw * eased));
499            if (p < 1) requestAnimationFrame(tick); else flicker();
500          })(st);
501        });
502      }, { threshold: 0.5 }).observe(row);
503    });
504  })();
505  </script>
505<script>
506  (function () {
507    var canvas = document.querySelector('.finale-warp');
508    if (!canvas) return;
509    var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
510    var ctx = canvas.getContext('2d'), W = 0, H = 0, raf = 0, running = false, stars = [];
511    for (var i = 0; i < 220; i++) stars.push({ x: Math.random() - 0.5, y: Math.random() - 0.5, z: Math.random() });
512    function resize() {
513      var r = canvas.getBoundingClientRect(); if (!r.width) return;
514      var dpr = Math.min(window.devicePixelRatio || 1, 2);
515      canvas.width = Math.round(r.width * dpr); canvas.height = Math.round(r.height * dpr);
516      ctx.setTransform(dpr, 0, 0, dpr, 0, 0); W = r.width; H = r.height;
517    }
518    function frame() {
519      ctx.fillStyle = 'rgba(23,24,24,0.30)'; ctx.fillRect(0, 0, W, H);
520      var cx = W / 2, cy = H / 2;
521      for (var i = 0; i < stars.length; i++) {
522        var o = stars[i]; o.z -= 0.006;
523        if (o.z <= 0.02) { o.x = Math.random() - 0.5; o.y = Math.random() - 0.5; o.z = 1; }
524        var k = 150 / o.z, k2 = 150 / (o.z + 0.03), a = Math.min(1, 1 - o.z);
525        ctx.strokeStyle = 'rgba(255,255,255,' + (a * 0.8) + ')'; ctx.lineWidth = a * 1.9;
526        ctx.beginPath(); ctx.moveTo(cx + o.x * k2, cy + o.y * k2); ctx.lineTo(cx + o.x * k, cy + o.y * k); ctx.stroke();
527      }
528    }
529    function loop() { if (!running) return; frame(); raf = requestAnimationFrame(loop); }
530    function start() { if (running || reduce) return; resize(); running = true; raf = requestAnimationFrame(loop); }
531    function stop() { running = false; cancelAnimationFrame(raf); }
532    new ResizeObserver(function () { if (running) resize(); }).observe(canvas);
533    var cta = document.querySelector('.finale .cta-finale') || document.querySelector('.finale');
534    ['pointerenter', 'focusin'].forEach(function (ev) { cta.addEventListener(ev, start); });
535    ['pointerleave', 'focusout'].forEach(function (ev) { cta.addEventListener(ev, stop); });
536  })();
537  </script>
537<footer class="site-footer" data-theme="dark"><div class="section-wrap"><div class="footer-top"><div class="footer-links"><div class="footer-linkgroup"><span class="footer-grouplabel">Services</span><div class="footer-chips"><a class="footer-chip" href="/paid-marketing">Paid Marketing</a><a class="footer-chip" href="/ai-search">AI Search</a><a class="footer-chip" href="/chatgpt-ads">ChatGPT Ads</a><a class="footer-chip" href="/story-systems">Story Systems</a><a class="footer-chip" href="/ad-creative">Ad Creative</a><a class="footer-chip" href="/landing-pages">Landing Pages</a></div></div><div class="footer-linkgroup"><span class="footer-grouplabel">Company</span><div class="footer-chips"><a class="footer-chip" href="/about">About</a><a class="footer-chip" href="/sponsorships">Sponsorships</a><a class="footer-chip" href="/careers">Careers</a></div></div><div class="footer-linkgroup"><span class="footer-grouplabel">Resources</span><div class="footer-chips"><a class="footer-chip" href="/newsletter">Growth Newsletter</a><a class="footer-chip" href="/frontier">The Frontier</a><a class="footer-chip" href="/growth-program">Growth Program</a></div></div><div class="footer-linkgroup"><span class="footer-grouplabel">Social</span><div class="footer-chips"><a class="footer-chip" href="https://www.linkedin.com/company/demandcurve/" target="_blank" rel="noopener">LinkedIn</a><a class="footer-chip" href="https://x.com/GrowthTactics" target="_blank" rel="noopener">Twitter / X</a></div></div></div></div><div class="footer-bottom"><span>© Demand Curve 2026</span><span class="footer-bottom-links"><a href="/legal/privacy">Privacy</a><a href="/legal/terms">Terms</a><a href="/legal/cookies">Cookies</a><a href="/">demandcurve.com</a></span></div></div></footer><section class="ascii-banner ascii-banner--closer" data-theme="dark"><div class="bigmark-fx" id="bigmark-fx" aria-hidden="true"><canvas id="pb-canvas"></canvas></div><h2 class="bigmark">Demand Curve</h2></section>
537<script>
538  /* -------- animated film grain: throttled ~12fps, pauses when hidden / reduced-motion -------- */
539  (function () {
540    // give each dropdown panel its own animated grain layer
541    document.querySelectorAll('.mega-panel').forEach(function (panel) {
542      if (panel.querySelector('.mega-noise')) return;
543      var c = document.createElement('span');   // static CSS-SVG grain, not an animated canvas
544      c.className = 'mega-noise';
545      panel.insertBefore(c, panel.firstChild);
546    });
547    var layers = [];
548    document.querySelectorAll('.noise-canvas, .cta-noise').forEach(function (canvas) {
549      var ctx = canvas.getContext('2d');
550      if (!ctx) return;
551      var o = { ctx: ctx, canvas: canvas, full: canvas.classList.contains('noise-canvas'), img: null };
552      alloc(o);
553      layers.push(o);
554    });
555    if (!layers.length) return;
556    // full-page grain renders at the DISPLAYED size (not a stretched 1024² buffer) so it stays a
557    // fine, crisp grain instead of upscaling into chunky blocks. Capped for perf; mobile gets a
558    // smaller buffer automatically.
559    function alloc(o) {
560      if (o.full) {
561        var dpr = Math.min(window.devicePixelRatio || 1, 2);
562        var w = (o.canvas.clientWidth || window.innerWidth) * dpr, h = (o.canvas.clientHeight || window.innerHeight) * dpr;
563        var s = Math.min(1, Math.sqrt(2600000 / (w * h)));   // render at device pixels (fine grain), capped for perf
564        o.canvas.width = Math.max(1, Math.round(w * s));
565        o.canvas.height = Math.max(1, Math.round(h * s));
566      }
567      o.img = o.ctx.createImageData(o.canvas.width, o.canvas.height);
568    }
569    function paint(o) {
570      var d = o.img.data;
571      for (var i = 0; i < d.length; i += 4) {
572        var v = (Math.random() * 255) | 0;
573        d[i] = v; d[i + 1] = v; d[i + 2] = v; d[i + 3] = 255;
574      }
575      o.ctx.putImageData(o.img, 0, 0);
576    }
577    layers.forEach(paint);   // one static frame
578    var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
579    var f = 0;
580    function loop() {
581      window.requestAnimationFrame(loop);
582      if (document.hidden) return;
583      if ((f++ % 5) !== 0) return;   // ~12fps throttle (lighter at the new resolution)
584      layers.forEach(paint);
585    }
586    if (!reduce) window.requestAnimationFrame(loop);   // reduced-motion: crisp static grain, no flicker
587    var rt;
588    window.addEventListener('resize', function () {
589      clearTimeout(rt);
590      rt = setTimeout(function () { layers.forEach(function (o) { if (o.full) alloc(o); }); layers.forEach(paint); }, 200);
591    });
592  })();
593
594
595  /* -------- trigger the staircase word reveal (must NOT wait on window.load,
596     or a slow background video keeps the hero title hidden) -------- */
597  (function () {
598    function startReveal() {
599      requestAnimationFrame(function () { document.body.classList.add('loaded'); });
600      setTimeout(function () { document.body.classList.add('reveal-done'); }, 1300);
601    }
602    if (document.readyState === 'interactive' || document.readyState === 'complete') startReveal();
603    else window.addEventListener('DOMContentLoaded', startReveal);
604  })();
605
606
607  /* -------- mega-menu dropdowns (shared by vertical nav + bar) -------- */
608  (function () {
609    var mega = document.querySelector('.mega');
610    if (!mega) return;
611    var panels = mega.querySelectorAll('.mega-panel');
612    var triggers = document.querySelectorAll('[data-menu]');
613    var scrim = mega.querySelector('.mega-scrim');
614    var canHover = window.matchMedia('(hover: hover)').matches;
615    var closeTimer = null;
616    var openTimer = null;
617    var current = null;
618
619    function open(name) {
620      clearTimeout(closeTimer); clearTimeout(openTimer);
621      current = name;
622      mega.classList.add('is-open');
623      mega.setAttribute('aria-hidden', 'false');
624      panels.forEach(function (p) { p.classList.toggle('is-active', p.getAttribute('data-panel') === name); });
625      triggers.forEach(function (t) { t.setAttribute('aria-expanded', String(t.getAttribute('data-menu') === name)); });
626    }
627    function close() {
628      clearTimeout(openTimer);
629      current = null;
630      mega.classList.remove('is-open');
631      mega.setAttribute('aria-hidden', 'true');
632      panels.forEach(function (p) { p.classList.remove('is-active'); });
633      triggers.forEach(function (t) { t.setAttribute('aria-expanded', 'false'); });
634    }
635    function scheduleClose() { clearTimeout(closeTimer); closeTimer = setTimeout(close, 200); }
636    function cancelClose() { clearTimeout(closeTimer); }
637
638    triggers.forEach(function (t) {
639      var name = t.getAttribute('data-menu');
640      // click toggles (also fires on Enter/Space for keyboard users)
641      t.addEventListener('click', function (e) { e.preventDefault(); clearTimeout(openTimer); (current === name) ? close() : open(name); });
642      if (canHover) {
643        // hover-intent: a quick graze past a trigger won't open it — you must rest ~140ms.
644        // If a panel is already open, moving onto another trigger switches instantly.
645        t.addEventListener('mouseenter', function () {
646          cancelClose();
647          if (current && current !== name) { open(name); }
648          else if (current !== name) { clearTimeout(openTimer); openTimer = setTimeout(function () { open(name); }, 140); }
649        });
650        t.addEventListener('mouseleave', function () { clearTimeout(openTimer); scheduleClose(); });
651      }
652    });
653    if (canHover) {
654      panels.forEach(function (p) {
655        p.addEventListener('mouseenter', cancelClose);
656        p.addEventListener('mouseleave', scheduleClose);
657      });
658    }
659    if (scrim) scrim.addEventListener('click', close);
660    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });
661    window.addEventListener('scroll', function () { if (current) close(); }, { passive: true });
662  })();
663
664
665  /* -------- nav morph: vertical list -> horizontal sticky bar -------- */
666  (function () {
667    var navStacked = document.querySelector('.nav-stacked');
668    var navBar = document.querySelector('.nav-bar');
669    var cta = document.querySelector('.cta');
670    var ctaCorners = document.querySelector('.cta-corners');
671    var sections = document.querySelectorAll('[data-theme]');
672    var mobileBar = document.querySelector('.mobile-bar');
673    var megaRoot = document.querySelector('.mega');
674    var SVC = (getComputedStyle(document.documentElement).getPropertyValue('--svc') || '#004AFF').trim();
675    var SVC_LIGHT = (function(h){h=(h||'').trim().replace('#','');if(h.length<6)return false;var r=parseInt(h.substr(0,2),16),g=parseInt(h.substr(2,2),16),b=parseInt(h.substr(4,2),16);return (0.299*r+0.587*g+0.114*b)/255 > 0.55;})(SVC);
676    var THEME_BG = { blue: 'rgba(0, 74, 255, 0.72)', dark: 'rgba(23, 24, 24, 0.82)', light: 'rgba(255, 255, 255, 0.82)', svc: 'color-mix(in srgb, ' + SVC + ' 82%, transparent)' };
677
678    function clamp(v) { return Math.max(0, Math.min(1, v)); }
679    function smooth(t) { return t * t * (3 - 2 * t); }
680    function pad() { return parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--pad-y')) || 48; }
681    // band inset, computed directly (getComputedStyle returns the unresolved max()/calc string)
682    function padX() { return Math.max(48, (window.innerWidth - 1800) / 2 + 48); }
683    function gut() { return parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--gut')) || 48; }
684
685    var BAR_H = 64;
686    var BIG = { w: 168, h: 52 }, SMALL = { w: 138, h: 44 };
687
688    function update() {
689      var vh = window.innerHeight;
690      var p = clamp(window.scrollY / (vh * 0.7));   // 0 at top, 1 once out of fold
691
692      // stacked nav fades + lifts away over first ~40% of the scroll
693      var out = clamp(p / 0.4);
694      navStacked.style.opacity = String(1 - out);
695      navStacked.style.transform = 'translateY(' + (-22 * out) + 'px)';
696      navStacked.style.pointerEvents = p > 0.4 ? 'none' : 'auto';
697
698      // sticky bar pops in over the back half (no slide)
699      var into = clamp((p - 0.45) / 0.55);
700      navBar.style.opacity = String(into);
701      navBar.style.pointerEvents = into > 0.5 ? 'auto' : 'none';
702
703      // match the bar's color to whatever section sits under it
704      var theme = (sections[0] && sections[0].getAttribute('data-theme')) || 'dark';
705      for (var s = 0; s < sections.length; s++) {
706        if (sections[s].getBoundingClientRect().top <= BAR_H) theme = sections[s].getAttribute('data-theme');
707        else break;
708      }
709      navBar.style.background = THEME_BG[theme] || THEME_BG.blue;
710      var SOLID = { svc: SVC, light: '#FCFCFF', dark: '#171818', blue: '#004AFF' };
711      document.documentElement.style.backgroundColor = SOLID[theme] || SVC;
712      var __tc = document.querySelector('meta[name=theme-color]'); if (__tc) __tc.setAttribute('content', SOLID[theme] || SVC);
713      navBar.classList.toggle('nav-bar--light', theme === 'light' || (theme === 'svc' && SVC_LIGHT));
714      if (megaRoot) {
715        megaRoot.classList.toggle('mega--blue', theme === 'blue');
716        var svcCssLight = document.body.classList.contains('svc-light');
717        megaRoot.classList.toggle('mega--svc', theme === 'svc' && svcCssLight);
718        megaRoot.classList.toggle('mega--svc-dark', theme === 'svc' && !svcCssLight);
719        megaRoot.classList.toggle('mega--dark', theme === 'dark');
720        megaRoot.classList.toggle('mega--light', theme === 'light');
721      }
722      if (mobileBar) {
723        mobileBar.style.background = THEME_BG[theme] || THEME_BG.blue;
724        mobileBar.classList.toggle('is-light', theme === 'light' || (theme === 'svc' && SVC_LIGHT));
725      }
726      var mMenu = document.querySelector('.mobile-menu');
727      if (mMenu) {
728        mMenu.style.background = ({ blue: 'var(--blue)', dark: 'var(--n900)', light: 'var(--white)', svc: 'var(--svc)' })[theme] || 'var(--blue)';
729        mMenu.classList.toggle('mm-light', theme === 'light' || (theme === 'svc' && SVC_LIGHT));
730      }
731
732      // hero CTA fades out with the stacked nav (no slide); the bar's contact button fades in
733      if (cta) {
734        cta.style.opacity = String(1 - out);
735        cta.style.pointerEvents = p > 0.4 ? 'none' : 'auto';
736      }
737    }
738
739    window.addEventListener('scroll', update, { passive: true });
740    window.addEventListener('resize', update);
741    update();
742  })();
743
744
745  /* -------- mobile hamburger menu -------- */
746  (function () {
747    var toggle = document.querySelector('.nav-toggle');
748    var menu = document.getElementById('mobile-menu');
749    if (!toggle || !menu) return;
750    function setOpen(open) {
751      document.body.classList.toggle('menu-open', open);
752      toggle.setAttribute('aria-expanded', String(open));
753      toggle.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
754      menu.setAttribute('aria-hidden', String(!open));
755    }
756    toggle.addEventListener('click', function () { setOpen(!document.body.classList.contains('menu-open')); });
757    menu.querySelectorAll('a').forEach(function (a) { a.addEventListener('click', function () { setOpen(false); }); });
758    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') setOpen(false); });
759  })();
760
761
762  /* -------- mobile: light up the service scrolled to the center (no hover on touch) -------- */
763  (function () {
764    if (!window.matchMedia('(max-width: 760px)').matches) return;
765    var rows = document.querySelectorAll('.srow');
766    if (!rows.length || !('IntersectionObserver' in window)) return;
767    var io = new IntersectionObserver(function (entries) {
768      entries.forEach(function (e) { e.target.classList.toggle('is-active', e.isIntersecting); });
769    }, { rootMargin: '-50% 0px -50% 0px', threshold: 0 });   // a thin band at the screen's center
770    rows.forEach(function (r) { io.observe(r); });
771  })();
772
773  </script>
773<script>
774  (function () {
775    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
776    var rp = document.querySelector('.robot-peek');
777    var cta = document.querySelector('.cta');
778    if (!rp || !cta) return;
779    var HID = -115, FULL = -22;                   // hidden | popped-out
780    var TOGGLE = 200, FLIPS = 8;
781    var prev = HID, waveIv = null, hovering = false;
782    function setTop(v) {
783      rp.style.transitionDuration = (v < prev) ? '0.16s' : '0.5s';   // slow pop out, fast snap back in
784      rp.style.top = v + 'px';
785      prev = v;
786    }
787    setTop(HID);
788    function startWave() { if (!waveIv) waveIv = setInterval(function () { rp.classList.toggle('f2'); }, TOGGLE); }
789    function stopWave() { if (waveIv) { clearInterval(waveIv); waveIv = null; } rp.classList.remove('f2'); }
790    // pop out + wave while hovering the Let's-talk CTA
791    cta.addEventListener('mouseenter', function () { hovering = true; setTop(FULL); startWave(); });
792    cta.addEventListener('mouseleave', function () { hovering = false; stopWave(); setTop(HID); });
793    // plus an occasional unprompted hello (skips while you're hovering / scrolled past the ATF)
794    function auto() {
795      if (hovering || window.scrollY > 500) return;
796      setTop(FULL); startWave();
797      setTimeout(function () { if (hovering) return; stopWave(); setTop(HID); }, FLIPS * TOGGLE);
798    }
799    setTimeout(auto, 6000);
800    setInterval(auto, 14000);
801    // the moment you start scrolling, snap him back in — a robot frozen mid-wave over the page looks off
802    window.addEventListener('scroll', function () {
803      if (window.scrollY > 40 && prev > HID) { hovering = false; stopWave(); setTop(HID); }
804    }, { passive: true });
805  })();
806</script>
806</body></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.