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">▾</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">▾</span></button><a class="navlink" href="/newsletter">Growth Newsletter</a><a class="navlink" href="/frontier">The Frontier<span class="nav-ext" aria-hidden="true">↗</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">▾</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">▾</span></button><a class="navlink" href="/newsletter">Growth Newsletter</a><a class="navlink" href="/frontier">The Frontier<span class="nav-ext" aria-hidden="true">↗</span></a><a class="nav-contact" href="/contact">Let'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'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'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">↗</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">→</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’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’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’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 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’s for</span><h2 class="wif-title">You’re in the right place if…</h2><ul class="wif-list"><li class="wif-row"><span class="wif-no">01</span><span class="wif-stmt">You’re growing, but it isn’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’t solved before.</span></li><li class="wif-row"><span class="wif-no">04</span><span class="wif-stmt">You’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’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’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’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">↗</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">↗</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">↗</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">↗</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">↗</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’ve optimized.</p><span class="svc-more">Learn more <span class="svc-arr" aria-hidden="true">↗</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">→</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’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ömer" loading="lazy"><span><b>Gustaf Alströ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 & 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 · 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 · 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×</span><span class="pe-cat">Conversions · 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">→</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’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 → 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">“One of the best partner relationships we have had.”</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 · 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 · 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 → 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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">— 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’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’ve rebuilt the agency model. What’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’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.</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’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.</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’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.</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’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.</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 “built-in distribution”?</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’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.</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’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.</p></div></div></div><div class="faq-item"><button class="faq-q" aria-expanded="false"><span class="faq-q-text">We’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’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. | #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. | #346 â Trade a trial extension for a review, spot where AI video crosses the line, and turn discounts into credits | #345 â Avoid shrinkflation, what to do when building in public stops working, and how to make your product a ritual. | #344 â How to increase desire, why Bezos picked books, exclude your refunders. | #343 â Unoptimized marketing, onboarding friction, and AI search | </span><span aria-hidden="true">â #348 â How I got 900k+ impressions from just 10 social posts. | #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. | #346 â Trade a trial extension for a review, spot where AI video crosses the line, and turn discounts into credits | #345 â Avoid shrinkflation, what to do when building in public stops working, and how to make your product a ritual. | #344 â How to increase desire, why Bezos picked books, exclude your refunders. | #343 â Unoptimized marketing, onboarding friction, and AI search | </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've been reading for a while, you'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 →</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 →</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'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">✦</span>Explore the full library<span class="orn" aria-hidden="true">✦</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’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, '&').replace(/</g, '<').replace(/>/g, '>'); 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, '&').replace(/</g, '<').replace(/>/g, '>'); 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, '&').replace(/</g, '<').replace(/>/g, '>'); 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">×</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, '&').replace(/</g, '<').replace(/>/g, '>'); } 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.