Blog  /  Outbound

Your GTM stack knows who to reach. It doesn’t know your boards.

Your sales intelligence contract tells your reps who to email. It can’t tell them what to say. For OOH operators, the gap between contact data and context data is where pipeline quietly dies.

By Thiru Saravanan·June 8, 2026·14 min read
GTM stack vs doohthis

Most growing OOH operators eventually sign up for a sales intelligence tool. ZoomInfo. Apollo. Lusha. LinkedIn Sales Navigator. Sometimes more than one. The annual contracts run between $15,000 and $80,000 depending on the seat count and feature tier. Most operators are paying for them right now.

These tools are good. They do something real. They tell your reps which advertiser contacts to reach, where those contacts work, what their titles are, how to email them, what the company's headcount and revenue look like, and which technologies the company uses. The contact database is genuinely better than anything an independent operator could build in-house, and the cost-per-contact is a fraction of what the same data cost a decade ago.

Six months after signing the contract, most operators are quietly disappointed. Outbound volume is up. Pipeline is not. The reps now know whom to email but still don't know what to say. The expensive tool became a fancier mail-merge engine for the same generic outreach the operator was sending before they had the tool.

This piece is about the gap between contact data and context data, why these tools cannot close that gap by design even when fully configured, and what OOH operators specifically need that sits on top of their existing GTM stack rather than in place of it.


What sales intelligence tools actually solve

The category of products variously called sales intelligence, sales engagement, or B2B contact data is solving a real problem. The problem is finding the right person at the right company.

Before these tools existed, a rep who wanted to reach the regional marketing manager at a Midwest grocery chain had to start with a Google search, work through LinkedIn, guess at email formats, and frequently end up sending cold messages to gatekeepers. The hit rate was bad and the cycle time was slow. Modern GTM tools collapsed that workflow. The rep now searches a database, filters by title and geography, exports a list, and has direct email addresses for fifty regional marketing managers at grocery chains across their footprint in fifteen minutes.

That is a genuine workflow improvement, and it is what these tools are properly understood as: a rolodex. The most current, most complete, most filterable rolodex the industry has ever had access to.

A rolodex is necessary. A rolodex is not sufficient.


What the rolodex doesn't tell you

The rep with a freshly exported list of fifty regional marketing managers at grocery chains has fifty names, fifty titles, fifty emails, and fifty company URLs. Depending on how the GTM stack is configured, they may also have a rich layer of brand activity signals — which of the fifty chains is expanding into which metros, which ones just announced a leadership change, which ones are entering a hiring sprint, which ones are launching private label this quarter, which ones are pushing into new categories, which ones are showing intent signals through their digital behavior. The better the GTM stack and the higher the tier, the richer that signal feed is.

Even with all of that turned on, the rep still does not have any of the following.

They do not know which specific boards on the operator's network sit in the trade areas of which specific store locations for each of those fifty chains. They do not know which corridors carry which chain's customer flow versus a competitor's. They do not know which boards own the morning-commute daypart that aligns with grocery shopping decision moments, or which boards face the wrong direction for that audience. They do not know which boards' contextual surroundings — the anchor retail, the residential density, the income mix of the immediate trade area — match each chain's positioning rather than its competitor's.

They do not know how a regional infrastructure change has shifted which audiences pass which boards on which days of the week. They do not know how a stadium opening twelve miles away changes the consumer-behavior gravity in their boards' immediate trade area. They do not know how this summer's tourism corridor traffic patterns differ from last summer's because the regional festival circuit expanded.

They do not know what to say to any of these fifty people that would distinguish their email from the other forty-three sales emails those marketing managers received this week — because the what to say depends on the synthesis between the brand activity signals the GTM stack is surfacing and the inventory and context layer the GTM stack does not.

This is the actual gap. Not the brand activity signals — those are increasingly available, and the better GTM tools provide them well. The gap is the layer underneath: the operator's own inventory DNA, refreshed against the live context around each board, as the substrate against which all of the brand signals get matched to specific assets.


The two kinds of data sales teams actually need

It's useful to separate sales data into two categories, because operators frequently treat their GTM stack as if it covers both — and end up over-investing in the one they already have while neglecting the one they don't.

The first category is brand and contact data. Who the buyers are at each target company, how to reach them, what their titles are, what's changing at their companies, what they're launching, where they're expanding, who they're hiring, what intent signals their digital behavior is throwing off. This is the territory of the modern GTM stack, and the better tools — properly configured and properly paid for — cover it well. They answer the questions who do I reach and what are these companies doing.

The second category is inventory and context data, and this is the one the GTM stack does not cover by design. It is the operator's own assets — which boards, in which corridors, with which audience profiles, daypart splits, seasonal patterns, contextual relevance — combined with the live conditions around each board that determine which advertiser activities those assets are positioned to capture. The inventory and context layer answers the question given everything we now know about the buyer's company, which of my specific boards are the right answer for them this quarter, and why.

The first category is broadly available and increasingly commoditized. The second category, for OOH specifically, has barely existed as a category. The reason it does not exist in the GTM stack is structural — the GTM stack's customers are software companies, professional services firms, and SaaS sales teams. Those customers don't need to know which trade area sits behind which billboard. They need to know that the target company has a procurement department and how to reach the procurement director. The GTM vendor's roadmap reflects who pays them.

The OOH operator who has been hoping the GTM stack would eventually surface OOH-relevant inventory matching has been waiting for a feature that is not on anyone's roadmap because the buyer for that feature is too small a fraction of the vendor's customer base to justify building it. The wait was always going to be infinite.


What an OOH-specific context layer actually looks like

If the GTM stack answers who do I reach and what are these companies doing, the OOH-specific context layer answers three further questions in sequence.

Where is this advertiser, geographically and contextually, relative to my specific inventory? Which of my boards are in this advertiser's trade area. Which corridors carry their actual customer flow. Which boards are positioned at decision moments for their category. The mapping from advertiser activity to specific assets on my specific network — the layer no horizontal tool can provide because no horizontal tool knows what my network is.

Why is this advertiser a good fit for this specific board, in this specific moment? The intersection of board-level audience composition, vertical-level fit logic, brand-level current activity, and seasonal alignment. Not generic relevance — specific relevance, refreshed weekly, against an inventory model that understands the operator's assets at the individual face level.

What should the rep actually say in the first email? The synthesis. Given the brand activity signal coming from the GTM stack, the inventory match coming from the operator's network, and the live context shaping the trade areas around each board, what is the angle that turns this contact's inbox from “another generic OOH email” into “this operator actually understood my Q2 priorities and brought me a specific answer.”

The three questions stack on top of the brand and contact layer the GTM stack already provides. They are not a replacement — they are the OOH-specific synthesis that turns horizontal sales intelligence into specific outreach against specific inventory at specific moments. Without them, even a fully-loaded GTM stack produces generic outreach with current contacts attached. With them, the rep walks into every call with the synthesis already done.


Why operators have been quietly underutilizing their sales data stack

The honest reason most operators are disappointed with their sales intelligence investment six months in is that they bought brand and contact data thinking it would solve an inventory matching problem.

The pattern is consistent. Operator signs the contract. Operator instructs the sales team to use it. Sales team uses it to build outreach lists. The lists are bigger and cleaner than before. The outreach volume goes up. Conversion does not, because the outreach itself is unchanged — generic introduction emails sent to a larger universe of generic contacts.

Six to twelve months in, the operator concludes that the tool “doesn't work” or “isn't worth what we paid” or “is fine but not transformative.” They renew the contract because the sales team would complain if they didn't, but they move it to the budget cost-cutting list.

The diagnosis is wrong. The tool is working. It is solving the problem it was built to solve. The reason pipeline didn't move is that the problem the tool solves was not actually the binding constraint on the operator's outbound motion. The binding constraint was inventory and context matching, and the operator did not buy that.

The fix is not to cut the GTM tool. The fix is to add the layer the GTM tool was never built to be. Brand and contact data plus inventory and context data, working together, is what produces the conversion lift the operator was originally hoping for. Either one alone, no matter how good, will not.


The integration logic, briefly

A reasonable question, if the argument above lands, is what the practical integration looks like between an existing GTM stack and an OOH-specific context layer.

The shortest version: the GTM stack is the source of truth for who to reach and what those companies are doing. The context layer is the source of truth for which of my boards are positioned for it, and what to say. The two systems talk to each other at the moment outreach is being prepared.

The rep, working from the context layer, sees a brand activity signal flow in from the GTM stack — a regional QSR chain announcing a Q2 value-menu push. The context layer surfaces five boards on the operator's network positioned for that push, along with the brand-specific story angle for each. The rep then pulls from the GTM stack the right contacts at that QSR chain — the regional marketing manager, the agency of record's planner, the franchisee marketing lead — and the context layer drafts the outreach using brand activity, inventory match, and live trade-area context simultaneously.

The email that lands on the regional marketing manager's desk references their specific company, their specific upcoming push, the specific boards on the specific routes their stores sit on, and offers a specific schedule for the launch window. The brand and contact data put the email in the right inbox with the right context about the recipient's company. The inventory and context data made it the email that gets read.

That integration is the actual workflow. The GTM stack and the context layer are complementary, not competitive. The mistake operators make is buying the first and assuming it will do the job of both.


The GTM stack with the doohthis context layer on top.
The GTM stack with the doohthis context layer on top.

The frame worth holding

OOH operators have been spending real money on sales intelligence tools for the last five years and getting a fraction of the return they expected. The reason is not that the tools are bad. The reason is that the tools are solving a different problem than the one the operator's outbound motion actually has.

The tools are excellent rolodexes. OOH operators need a rolodex and a context engine. The rolodex tells the rep whom to email. The context engine tells the rep why now, why this board, and what to actually say. Without the second layer, the rolodex produces more outbound volume but not more pipeline.

The operators reading this who are renewing GTM contracts in 2026 should ask a different question than the one they've been asking. The question is not is the contract worth it. It is is the contract working as a contact and signal database while we add the contextual and inventory layer that turns those contacts and signals into conversations. The first question has a defensive answer (yes, technically, the data is fine). The second question has a strategic answer: the data is only worth what gets done with it, and what's been missing for ten years is the layer that turns it into conversations.

The operators who treat their sales intelligence spend as the floor of their sales data investment, not the ceiling, will spend the next decade out-converting the operators who treat it as a complete solution. The rolodex is necessary. It was never going to be sufficient.


doohthis is the OOH context engine that sits on top of your GTM stack. Your existing tools tell you whom to reach and what their companies are doing. doohthis tells you which of your boards are positioned for it, and what to say. If you're paying for the rolodex but not getting the pipeline, we should talk.

Sell smarter

See it on your own boards.

Thirty minutes, your inventory, real recommendations.

<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>doohthis | Know who to sell, when, and why</title> <meta name="description" content="The revenue engine for out-of-home operators. doohthis reads every board's location DNA and tells your team who to sell, when, and why."> <link rel="icon" href="/assets/favicon.png?v=3"> <style> @font-face{font-family:'NHD';src:url(/fonts/NeueHaasDisplayLight.ttf);font-weight:300} @font-face{font-family:'NHD';src:url(/fonts/NeueHaasDisplayRoman.ttf);font-weight:400} @font-face{font-family:'NHD';src:url(/fonts/NeueHaasDisplayMediu.ttf);font-weight:500} @font-face{font-family:'Labil';src:url(/fonts/LabilGrotesk-Regular.ttf);font-weight:400} @font-face{font-family:'Labil';src:url(/fonts/LabilGrotesk-Medium.ttf);font-weight:500} @font-face{font-family:'Labil';src:url(/fonts/LabilGrotesk-Bold.ttf);font-weight:700} :root{--ink:#0B0620;--ink2:#1B1A22;--body:#55535F;--mute:#8B8A94;--line:#E6E5EC;--line2:#EFEEF3;--bg:#FAFAFC;--v:#5413B8;--v2:#7A2BD9;--amb:#D9834F;--amb2:#FEB34B;--disp:'NHD','Helvetica Neue',Arial,sans-serif;--sans:'NHD','Helvetica Neue',Arial,sans-serif;--mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace} *{box-sizing:border-box;margin:0;padding:0} html{scroll-behavior:smooth} body{overflow-x:clip;font-family:var(--sans);color:var(--ink2);background:#fff;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility} a{color:var(--v);text-decoration:none}a:hover{color:var(--v2)} .wrap{max-width:1200px;margin:0 auto;padding:0 32px} .lab{font-family:var(--mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--mute)} .btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--sans);font-weight:500;font-size:15px;border-radius:999px;padding:14px 22px;transition:transform .2s,background .2s,box-shadow .2s;white-space:nowrap} .btn:hover{transform:translateY(-1px)} .btn-w{background:#fff;color:var(--ink)}.btn-w:hover{color:var(--ink);box-shadow:0 10px 30px rgba(255,255,255,.18)} .btn-g{border:1px solid rgba(255,255,255,.28);color:#fff}.btn-g:hover{color:#fff;background:rgba(255,255,255,.08)} .btn-v{background:linear-gradient(135deg,#1A0B3D,#4A12A8 60%,#7A2BD9);color:#fff}.btn-v:hover{color:#fff;box-shadow:0 12px 30px rgba(84,19,184,.3)} .btn-o{border:1px solid var(--line);color:var(--ink2);background:#fff}.btn-o:hover{color:var(--ink2);border-color:#cfcdd8} h1,h2,h3{font-family:var(--disp);font-weight:500;letter-spacing:-.025em;color:var(--ink)} h2{font-size:clamp(34px,4.6vw,56px);line-height:1.04;text-wrap:balance} p{text-wrap:pretty} /* NAV */ .nav{position:fixed;top:0;left:0;right:0;z-index:50;transition:background .3s,border-color .3s,backdrop-filter .3s;border-bottom:1px solid transparent} .nav.solid{background:rgba(11,6,32,.72);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-color:rgba(255,255,255,.08)} .nav .in{display:flex;align-items:center;gap:28px;height:72px} .logo{font-family:var(--disp);font-weight:500;font-size:24px;letter-spacing:-.04em;color:#fff}.logo:hover{color:#fff} .nav .links{display:flex;gap:26px;flex:1} .nav .links a{color:rgba(255,255,255,.72);font-size:14.5px}.nav .links a:hover{color:#fff} .nav .act{display:flex;gap:10px;align-items:center} .nav .act .login{color:rgba(255,255,255,.8);font-size:14.5px;padding:0 6px} .nav .act .btn{padding:10px 18px;font-size:14px} @media(max-width:960px){.nav .links{display:none}.nav .in{justify-content:space-between}} /* HERO */ .hero{position:relative;overflow:hidden;background:#0B0620;color:#fff;padding:150px 0 0} .mesh{position:absolute;inset:-20%;background:radial-gradient(40% 50% at 78% 30%,rgba(217,131,79,.55),transparent 70%),radial-gradient(45% 55% at 20% 70%,rgba(84,19,184,.55),transparent 70%),radial-gradient(35% 40% at 55% 85%,rgba(122,43,217,.45),transparent 70%),linear-gradient(135deg,#0B0620,#1A0B3D 50%,#24105C);filter:saturate(1.1);animation:drift 22s ease-in-out infinite alternate} @keyframes drift{0%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(-3%,2%,0) scale(1.05)}100%{transform:translate3d(2%,-2%,0) scale(1.02)}} .grain{position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);background-size:64px 64px;mask-image:radial-gradient(70% 60% at 50% 30%,#000,transparent)} .hero .wrap{position:relative} .eyebrow{white-space:nowrap;max-width:100%;display:inline-flex;align-items:center;gap:10px;border:1px solid rgba(255,255,255,.18);border-radius:999px;padding:7px 14px 7px 8px;font-size:13px;color:rgba(255,255,255,.82);background:rgba(255,255,255,.04)} .eyebrow b{font-family:var(--mono);font-weight:400;font-size:11px;letter-spacing:.06em;background:linear-gradient(90deg,var(--v2),var(--amb));border-radius:999px;padding:3px 9px;color:#fff} .hero h1{font-size:clamp(46px,7.6vw,104px);line-height:.96;letter-spacing:-.045em;color:#fff;margin-top:26px;max-width:1000px} .hero h1 em{font-style:normal;background:linear-gradient(90deg,#fff 0%,#E9C9FF 40%,#FFC38A 100%);-webkit-background-clip:text;background-clip:text;color:transparent} .hero .sub{font-size:clamp(17px,1.6vw,20px);line-height:1.55;color:rgba(255,255,255,.72);max-width:620px;margin-top:26px} .hero .ctas{display:flex;gap:12px;flex-wrap:wrap;margin-top:34px} .built{display:flex;gap:10px 22px;flex-wrap:wrap;align-items:center;margin-top:30px;font-size:13.5px;color:rgba(255,255,255,.6)} .built span.dot{width:4px;height:4px;border-radius:2px;background:rgba(255,255,255,.3)} /* ENGINE DEMO */ .demo{position:relative;margin-top:72px;border-radius:22px 22px 0 0;border:1px solid rgba(255,255,255,.12);border-bottom:none;background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.02));backdrop-filter:blur(8px);padding:22px 22px 0;box-shadow:0 -30px 80px rgba(84,19,184,.25)} .demo-top{display:flex;align-items:center;gap:10px;padding:0 4px 16px} .demo-top .d{width:10px;height:10px;border-radius:5px;background:rgba(255,255,255,.18)} .demo-top .t{font-family:var(--mono);font-size:12px;color:rgba(255,255,255,.55);margin-left:8px} .flow{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px} .stage{background:#fff;color:var(--ink2);border-radius:16px 16px 0 0;padding:18px 18px 22px;min-height:290px;position:relative;opacity:.38;transform:translateY(8px);transition:opacity .6s,transform .6s} .stage.on{opacity:1;transform:none} .stage .n{display:flex;justify-content:space-between;align-items:center} .stage .n .lab{color:var(--v)} .stage h4{font-family:var(--disp);font-weight:500;font-size:19px;letter-spacing:-.02em;margin-top:8px;color:var(--ink)} .board{margin-top:14px;aspect-ratio:3/1;border-radius:8px;background:linear-gradient(135deg,#24105C,#5413B8 60%,#D9834F);display:flex;align-items:flex-end;padding:10px;color:#fff;font-family:var(--mono);font-size:11px} .kv{margin-top:12px;display:grid;gap:7px} .kv div{display:flex;justify-content:space-between;font-size:13px;color:var(--body);border-bottom:1px dashed var(--line);padding-bottom:6px} .kv b{color:var(--ink2);font-weight:500} .layers{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px} .layers span{font-size:12px;border:1px solid var(--line);border-radius:999px;padding:4px 10px;color:var(--body);background:var(--bg);transition:all .4s} .stage.on .layers span.hit{border-color:#D8C6F5;background:#F6F0FF;color:var(--v)} .bars{margin-top:14px;display:grid;gap:10px} .bar .r{display:flex;justify-content:space-between;font-size:13px;margin-bottom:5px}.bar .r b{font-weight:500} .bar .tr{height:6px;border-radius:3px;background:var(--line2);overflow:hidden} .bar .fl{height:100%;width:0;border-radius:3px;background:linear-gradient(90deg,var(--v),var(--amb));transition:width 1.1s cubic-bezier(.2,.7,.2,1)} .why{margin-top:12px;font-size:12.5px;line-height:1.5;color:var(--body);background:var(--bg);border-radius:10px;padding:10px 12px} .mail{margin-top:12px;border:1px solid var(--line);border-radius:12px;padding:12px;font-size:13px;line-height:1.55;color:var(--body)} .mail .to{font-family:var(--mono);font-size:11px;color:var(--mute);margin-bottom:6px} .mail .typed{color:var(--ink2);min-height:84px} .mail .typed::after{content:'';display:inline-block;width:7px;height:14px;background:var(--v);vertical-align:-2px;margin-left:2px;animation:blink 1s steps(1) infinite} @keyframes blink{50%{opacity:0}} .send{margin-top:10px;display:inline-flex;font-size:12.5px;font-weight:500;color:#fff;background:var(--ink);border-radius:999px;padding:7px 13px} @media(max-width:960px){.flow{grid-template-columns:repeat(2,minmax(0,1fr))}.stage{border-radius:16px;margin-bottom:14px}.demo{padding-bottom:8px}} @media(max-width:560px){.flow{grid-template-columns:1fr}} /* SECTIONS */ section{padding:120px 0} .head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px;align-items:end;margin-bottom:56px} .head p{font-size:18px;line-height:1.6;color:var(--body);max-width:520px} @media(max-width:860px){.head{grid-template-columns:1fr}} .rule{height:2px;border-radius:2px;background:linear-gradient(90deg,#24105C,var(--v) 55%,var(--amb));width:64px;margin-bottom:22px} /* PROBLEM */ .prob{background:var(--bg);border-top:1px solid var(--line2);border-bottom:1px solid var(--line2)} .ba{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px} .ba .c{border-radius:20px;padding:34px;border:1px solid var(--line);background:#fff} .ba .c.after{background:linear-gradient(160deg,#0E0726,#1F0E50 60%,#3A1590);border:none;color:#fff} .ba .c .lab{margin-bottom:18px}.ba .c.after .lab{color:#B9A9EA} .ba ul{list-style:none;display:grid;gap:14px} .ba li{display:flex;gap:12px;font-size:16.5px;line-height:1.5;color:var(--body)} .ba .after li{color:#E6E0F5} .ba li i{flex:none;width:20px;height:20px;border-radius:10px;margin-top:2px;display:flex;align-items:center;justify-content:center;font-style:normal;font-size:11px;background:var(--line2);color:var(--mute)} .ba .after li i{background:linear-gradient(135deg,var(--v2),var(--amb));color:#fff} @media(max-width:860px){.ba{grid-template-columns:1fr}} /* PILLARS */ .tabs{display:inline-flex;gap:4px;padding:5px;border:1px solid var(--line);border-radius:999px;background:#fff;margin-bottom:28px} .tabs button{font-family:var(--sans);font-size:15px;font-weight:500;border:none;background:none;color:var(--body);padding:10px 20px;border-radius:999px;cursor:pointer;transition:all .25s} .tabs button.on{background:var(--ink);color:#fff} .pill{display:none;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:28px} .pill.on{display:grid;animation:fade .5s ease} @keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}} .pill .intro h3{font-size:clamp(28px,3vw,40px);line-height:1.08} .pill .intro p{font-size:17px;line-height:1.6;color:var(--body);margin-top:16px} .pill .intro .tag{display:inline-block;margin-top:22px;font-size:13px;color:var(--v);background:#F6F0FF;border-radius:999px;padding:6px 12px} .pill .intro .btn{margin-top:28px} .steps{border:1px solid var(--line);border-radius:20px;overflow:hidden;background:#fff} .steps .s{display:grid;grid-template-columns:56px minmax(0,1fr);gap:4px;padding:22px 24px;border-top:1px solid var(--line2);transition:background .25s} .steps .s:first-child{border-top:none} .steps .s:hover{background:var(--bg)} .steps .s .k{font-family:var(--mono);font-size:12px;color:var(--v);padding-top:4px} .steps .s h4{font-family:var(--disp);font-weight:500;font-size:19px;color:var(--ink);letter-spacing:-.015em;display:flex;gap:10px;align-items:center} .steps .s h4 span{font-family:var(--mono);font-size:10.5px;font-weight:400;letter-spacing:.06em;color:#fff;background:linear-gradient(90deg,var(--v),var(--amb));border-radius:999px;padding:3px 8px} .steps .s p{font-size:15px;line-height:1.55;color:var(--body);margin-top:4px} @media(max-width:860px){.pill.on{grid-template-columns:1fr}} /* DNA */ .dna{background:#0B0620;color:#fff;position:relative;overflow:hidden} .dna .mesh{opacity:.55} .dna .wrap{position:relative} .dna h2{color:#fff}.dna .head p{color:rgba(255,255,255,.7)}.dna .lab{color:#B9A9EA} .fuse{display:grid;grid-template-columns:minmax(0,1fr) 180px minmax(0,1fr);gap:24px;align-items:center} .col{border:1px solid rgba(255,255,255,.12);border-radius:20px;padding:26px;background:rgba(255,255,255,.04)} .col .big{font-family:var(--disp);font-size:64px;font-weight:500;letter-spacing:-.04em;line-height:1} .col .big small{font-size:18px;letter-spacing:0;color:rgba(255,255,255,.6);margin-left:8px} .col .chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:18px} .col .chips span{font-size:12.5px;border:1px solid rgba(255,255,255,.16);border-radius:999px;padding:5px 11px;color:rgba(255,255,255,.82)} .core{aspect-ratio:1;border-radius:50%;background:radial-gradient(circle at 35% 30%,#FFC38A,#D9834F 25%,#7A2BD9 60%,#24105C);box-shadow:0 0 80px rgba(217,131,79,.45),0 0 140px rgba(122,43,217,.4);display:flex;align-items:center;justify-content:center;text-align:center;font-family:var(--disp);font-weight:500;font-size:17px;line-height:1.15;animation:pulse 5s ease-in-out infinite} @keyframes pulse{50%{box-shadow:0 0 110px rgba(217,131,79,.6),0 0 170px rgba(122,43,217,.5)}} .outs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;margin-top:24px} .outs div{border-top:1px solid rgba(255,255,255,.16);padding-top:16px} .outs b{display:block;font-family:var(--disp);font-weight:500;font-size:22px;letter-spacing:-.02em} .outs span{font-size:14.5px;color:rgba(255,255,255,.65);line-height:1.5;display:block;margin-top:6px} @media(max-width:900px){.fuse{grid-template-columns:1fr}.core{width:180px;margin:0 auto}.outs{grid-template-columns:1fr}} /* OUTCOMES */ .grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:20px;overflow:hidden} .grid3 .o{background:#fff;padding:30px 28px 32px;transition:background .25s} .grid3 .o:hover{background:var(--bg)} .grid3 .o .lab{color:var(--v)} .grid3 .o h4{font-family:var(--disp);font-weight:500;font-size:22px;letter-spacing:-.02em;color:var(--ink);margin-top:14px} .grid3 .o p{font-size:15px;line-height:1.55;color:var(--body);margin-top:8px} .grid3 .o .stat{display:inline-block;margin-top:16px;font-family:var(--mono);font-size:12px;color:var(--ink2);border:1px solid var(--line);border-radius:999px;padding:4px 10px} @media(max-width:900px){.grid3{grid-template-columns:1fr}} /* BLOG */ .posts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px} .post{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:20px;overflow:hidden;background:#fff;color:inherit;transition:transform .25s,box-shadow .25s} .post:hover{transform:translateY(-3px);box-shadow:0 20px 50px rgba(27,26,34,.08);color:inherit} .post .art{aspect-ratio:16/9;background:linear-gradient(135deg,#0B0620,#24105C 45%,#5413B8 80%,#D9834F 120%);position:relative} .post:nth-child(2) .art{background:linear-gradient(200deg,#0B0620,#3A1590 55%,#D9834F 130%)} .post:nth-child(3) .art{background:linear-gradient(160deg,#1A0B3D,#5413B8 70%,#FEB34B 130%)} .post .art span{position:absolute;left:16px;top:16px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:#fff;border:1px solid rgba(255,255,255,.3);border-radius:999px;padding:4px 10px} .post .b{padding:22px 22px 24px;display:flex;flex-direction:column;flex:1} .post .lab{margin-bottom:10px} .post h4{font-family:var(--disp);font-weight:500;font-size:20px;line-height:1.2;letter-spacing:-.015em;color:var(--ink)} .post p{font-size:14.5px;line-height:1.55;color:var(--body);margin-top:10px;flex:1} .post .more{margin-top:16px;font-size:14px;font-weight:500;color:var(--v)} @media(max-width:900px){.posts{grid-template-columns:1fr}} /* CTA */ .cta{padding:0 0 120px} .cta .box{position:relative;overflow:hidden;border-radius:28px;background:#0B0620;color:#fff;padding:88px 56px;text-align:center} .cta .box .mesh{opacity:.9} .cta .box>*{position:relative} .cta h2{color:#fff;max-width:820px;margin:0 auto} .cta p{font-size:18px;line-height:1.6;color:rgba(255,255,255,.72);max-width:560px;margin:18px auto 0} .cta .ctas{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:32px} @media(max-width:600px){.cta .box{padding:64px 24px}} /* FOOTER */ footer{border-top:1px solid var(--line);padding:64px 0 40px;background:#fff} .fgrid{display:grid;grid-template-columns:minmax(0,1.6fr) repeat(3,minmax(0,1fr));gap:32px} .fgrid .logo{color:var(--ink)} .fgrid p{font-size:14.5px;line-height:1.6;color:var(--body);margin-top:14px;max-width:340px} .fgrid h5{font-family:var(--mono);font-weight:400;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--mute);margin-bottom:14px} .fgrid ul{list-style:none;display:grid;gap:10px} .fgrid li a{color:var(--ink2);font-size:14.5px}.fgrid li a:hover{color:var(--v)} .fbot{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;align-items:center;margin-top:48px;padding-top:24px;border-top:1px solid var(--line2);font-size:13px;color:var(--mute)} .fbot .soc{display:flex;gap:16px}.fbot .soc a{color:var(--body)} .fbot .mem{display:flex;gap:18px;align-items:center}.fbot .mem img{height:28px;width:auto;opacity:.8} .geo{margin-top:16px;font-size:11.5px;color:var(--mute);line-height:1.5} @media(max-width:860px){.fgrid{grid-template-columns:1fr 1fr}} @media(prefers-reduced-motion:reduce){.mesh,.core{animation:none}.stage{transition:none}[data-r]{opacity:1!important;transform:none!important}} /* GEO + SEASON */ .geo{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:48px;align-items:center} .gmap{position:relative;aspect-ratio:1.15;border-radius:24px;overflow:hidden;background:radial-gradient(circle at 50% 50%,#F6F0FF,#FAFAFC 70%);border:1px solid var(--line)} .gmap .grd{position:absolute;inset:0;background-image:linear-gradient(var(--line2) 1px,transparent 1px),linear-gradient(90deg,var(--line2) 1px,transparent 1px);background-size:40px 40px;opacity:.8} .gmap .rd{position:absolute;left:-10%;right:-10%;top:52%;height:22px;margin-top:-11px;background:#E6E3EE;transform:rotate(-14deg);box-shadow:inset 0 0 0 1px #DAD6E4} .gmap .rd::after{content:'';position:absolute;left:0;right:0;top:50%;border-top:2px dashed #fff} .gmap .rd2{position:absolute;top:-10%;bottom:-10%;left:63%;width:14px;background:#ECE9F2;transform:rotate(8deg)} .gmap .ring{position:absolute;left:50%;top:52%;border-radius:50%;transform:translate(-50%,-50%) scale(.6);opacity:0;transition:transform 1.2s cubic-bezier(.2,.7,.2,1),opacity 1s} .gmap .ring.r1{width:30%;aspect-ratio:1.25;background:rgba(84,19,184,.16);border:1.5px solid rgba(84,19,184,.45)} .gmap .ring.r2{width:58%;aspect-ratio:1.35;background:rgba(122,43,217,.08);border:1.5px dashed rgba(122,43,217,.4);transition-delay:.15s} .gmap .ring.r3{width:86%;aspect-ratio:1.45;background:rgba(217,131,79,.05);border:1.5px dashed rgba(217,131,79,.45);transition-delay:.3s} .gmap.go .ring{transform:translate(-50%,-50%) scale(1);opacity:1} .gmap .rl{position:absolute;font-family:var(--mono);font-size:10.5px;color:var(--v);background:#fff;border-radius:6px;padding:2px 6px;border:1px solid #E4D8FA} .gmap .pin{position:absolute;left:50%;top:52%;width:20px;height:20px;margin:-10px 0 0 -10px;border-radius:50%;background:linear-gradient(135deg,var(--v),var(--amb));box-shadow:0 0 0 6px rgba(84,19,184,.15),0 8px 20px rgba(84,19,184,.35);z-index:3} .gmap .fc{position:absolute;left:50%;top:52%;width:70px;height:70px;margin:-70px 0 0 -6px;transform-origin:6px 70px;transform:rotate(62deg);background:conic-gradient(from -18deg at 6px 70px,transparent 0deg,rgba(254,179,75,.45) 0deg 36deg,transparent 36deg);z-index:2;border-radius:0 70px 0 0} .gmap .an{position:absolute;display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--ink2);background:#fff;border:1px solid var(--line);border-radius:999px;padding:4px 9px 4px 5px;white-space:nowrap;box-shadow:0 6px 16px rgba(27,26,34,.06);opacity:0;transform:translateY(8px);transition:all .6s} .gmap.go .an{opacity:1;transform:none} .gmap .an i{width:10px;height:10px;border-radius:50%;flex:none} .gmap .an.x i{background:#C2341C}.gmap .an.a i{background:var(--v)}.gmap .an.b i{background:var(--amb)} .gmap .flow{position:absolute;left:14%;top:66%;font-family:var(--mono);font-size:10.5px;color:var(--body);transform:rotate(-14deg)} .gfac{display:grid;gap:4px} .gfac div{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px;padding:16px 0;border-top:1px solid var(--line2)} .gfac div:first-child{border-top:none} .gfac .k{font-family:var(--mono);font-size:12px;color:var(--v);padding-top:3px} .gfac b{font-family:var(--disp);font-weight:500;font-size:19px;letter-spacing:-.015em;color:var(--ink)} .gfac p{font-size:15px;line-height:1.55;color:var(--body);margin-top:4px} @media(max-width:900px){.geo{grid-template-columns:1fr}} .sea{background:#0B0620;color:#fff;position:relative;overflow:hidden} .sea .mesh{opacity:.45}.sea .wrap{position:relative}.sea h2{color:#fff}.sea .head p{color:rgba(255,255,255,.7)}.sea .lab{color:#B9A9EA} .cal{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;margin-bottom:22px} .cal div{border:1px solid rgba(255,255,255,.12);border-radius:16px;padding:18px 20px;background:rgba(255,255,255,.04)} .cal b{display:flex;align-items:center;gap:9px;font-family:var(--disp);font-weight:500;font-size:20px;letter-spacing:-.02em} .cal b i{width:12px;height:12px;border-radius:4px} .cal p{font-size:14.5px;line-height:1.55;color:rgba(255,255,255,.68);margin-top:6px} .sw{border:1px solid rgba(255,255,255,.12);border-radius:22px;background:rgba(255,255,255,.04);padding:22px} .sw .mo{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:4px} .sw .mo button{font-family:var(--mono);font-size:11px;letter-spacing:.04em;border:none;border-radius:8px;padding:9px 0;background:rgba(255,255,255,.06);color:rgba(255,255,255,.6);cursor:pointer;transition:all .25s} .sw .mo button.on{background:#fff;color:var(--ink)} .sw .bd{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:22px;margin-top:20px} .sw .top4{display:grid;gap:10px;align-content:start} .sw .tv{border-radius:14px;padding:12px 14px;background:rgba(255,255,255,.06);transition:all .4s} .sw .tv .r{display:flex;justify-content:space-between;align-items:baseline;gap:10px} .sw .tv b{font-family:var(--disp);font-weight:500;font-size:17px;letter-spacing:-.015em} .sw .tv .sc{font-family:var(--mono);font-size:13px;color:#FFC38A} .sw .tv .tr{height:5px;border-radius:3px;background:rgba(255,255,255,.1);margin-top:8px;overflow:hidden} .sw .tv .fl{height:100%;border-radius:3px;background:linear-gradient(90deg,var(--v2),var(--amb));transition:width .6s cubic-bezier(.2,.7,.2,1)} .sw .tv .why{display:flex;align-items:center;gap:7px;font-size:12.5px;color:rgba(255,255,255,.72);margin-top:8px} .sw .tv .why i{width:9px;height:9px;border-radius:3px;flex:none} .sw .hm{display:grid;grid-template-columns:minmax(110px,auto) repeat(12,minmax(0,1fr));gap:3px;align-items:center;font-size:12px} .sw .hm .vl{color:rgba(255,255,255,.72);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:6px} .sw .hm .c{height:20px;border-radius:4px;transition:outline-color .25s;outline:2px solid transparent;outline-offset:-1px} .sw .hm .c.cur{outline-color:#fff} .sw .hm .mh{font-family:var(--mono);font-size:9.5px;color:rgba(255,255,255,.45);text-align:center} .sw .hm .mh.cur{color:#fff} .sw .ft{display:flex;gap:16px;flex-wrap:wrap;margin-top:14px;font-size:12px;color:rgba(255,255,255,.6)} .sw .ft span{display:flex;align-items:center;gap:6px}.sw .ft i{width:10px;height:10px;border-radius:3px} @media(max-width:900px){.cal{grid-template-columns:1fr}.sw .bd{grid-template-columns:1fr}.sw .mo{grid-template-columns:repeat(6,minmax(0,1fr))}} .duo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:18px;perspective:1200px} .duo .c{border-radius:24px;padding:40px 36px;border:1px solid var(--line);background:#fff;position:relative;overflow:hidden} .duo .c.dk{background:linear-gradient(160deg,#0E0726,#1F0E50 60%,#3A1590);border:none;color:#fff} .duo .c .lab{color:var(--v)}.duo .c.dk .lab{color:#FFC38A} .duo h3{font-size:clamp(28px,3vw,38px);line-height:1.06;margin-top:14px} .duo .c.dk h3{color:#fff} .duo p{font-size:16.5px;line-height:1.6;color:var(--body);margin-top:14px} .duo .c.dk p{color:rgba(255,255,255,.72)} .duo ul{list-style:none;display:grid;gap:12px;margin-top:22px} .duo li{display:flex;gap:12px;font-size:15.5px;line-height:1.5;color:var(--ink2)} .duo .c.dk li{color:#E6E0F5} .duo li::before{content:'';flex:none;width:7px;height:7px;border-radius:4px;margin-top:8px;background:linear-gradient(135deg,var(--v),var(--amb))} @media(max-width:860px){.duo{grid-template-columns:1fr}} /* SCROLL 3D */ .hero{perspective:1400px} .demo{transform-origin:50% 0;will-change:transform} .flow{transform-style:preserve-3d} .stage{will-change:transform} [data-r]{opacity:0;transform:perspective(1000px) translate3d(0,60px,-80px) rotateX(14deg);transition:opacity .9s cubic-bezier(.2,.7,.2,1),transform 1.1s cubic-bezier(.2,.7,.2,1)} [data-r].in{opacity:1;transform:none} [data-r="l"]{transform:perspective(1000px) translate3d(-60px,30px,0) rotateY(18deg)} [data-r="rr"]{transform:perspective(1000px) translate3d(60px,30px,0) rotateY(-18deg)} [data-r].in{transform:none} .ba,.steps,.grid3,.posts,.fuse{perspective:1200px} .tilt{transform-style:preserve-3d;transition:transform .25s ease-out} .col .chips span{white-space:nowrap} .col .ct{font-family:var(--disp);font-size:clamp(24px,2.4vw,30px);font-weight:500;letter-spacing:-.025em;line-height:1.1} .col .cs{font-size:14.5px;line-height:1.5;color:rgba(255,255,255,.62);margin-top:8px} .core{will-change:transform} .cta .box{transform-origin:50% 100%;will-change:transform} </style> <link rel="stylesheet" href="/frontier.css"> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script>function initApollo(){var n=Math.random().toString(36).substring(7),o=document.createElement("script"); o.src="https://assets.apollo.io/micro/website-tracker/tracker.iife.js?nocache="+n,o.async=!0,o.defer=!0, o.onload=function(){window.trackingFunctions.onLoad({appId:"677ab51ad39e0302d01d8498"})}, document.head.appendChild(o)}initApollo();</script> <!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-Z1PRKMG1X4"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-Z1PRKMG1X4'); </script> </head> <body> <header class="nav" id="nav"><div class="wrap in"><a class="logo" href="/">doohthis</a><nav class="links"><a href="/how-it-works">How it works</a><a href="/outbound">Outbound</a><a href="/inbound">Inbound</a><a href="/grow">Grow</a><a href="/about">About</a><a href="/faq">FAQ</a><a href="/news">News</a><a href="/blog">Blog</a></nav><div class="act"><a class="login" href="https://app.doohthis.com/">Log in</a><a class="btn btn-w" href="/book-demo">Book a demo</a></div></div></header> <!-- HERO --> <div class="hero"> <div class="mesh"></div><div class="grain"></div> <div class="wrap"> <span class="eyebrow"><b>AI SALES SUITE</b>Built for out-of-home</span> <h1>Sell every board.<br><em>Win the advertisers OOH never had.</em></h1> <p class="sub">doohthis is the AI suite behind the people who sell billboards. It studies each of your boards in depth and gives your reps the local knowledge they need to sell it, the businesses around it, the people who pass it and how its audience shifts through the year, then finds the businesses that belong on it and makes the case in their own language, including the thousands that have never bought out-of-home advertising.</p> <div class="ctas"><a class="btn btn-w" href="/book-demo">Book a demo &rarr;</a><a class="btn btn-g" href="/how-it-works">See how it works</a><button type="button" class="btn btn-g hx-btn" id="hero-explainer-btn" data-testid="hero-watch-explainer-btn"><span class="hx-ic"></span>Watch explainer</button></div> <div class="built"><span>Built for</span><span class="dot"></span><span>Static &amp; digital billboards</span><span class="dot"></span><span>Transit media</span><span class="dot"></span><span>Street furniture</span><span class="dot"></span><span>Urban panels</span><span class="dot"></span><span>Place-based media</span></div> <div class="demo" id="how" aria-label="How doohthis works on one board"> <div class="demo-top"><span class="d"></span><span class="d"></span><span class="d"></span><span class="t">one board, start to pitch &middot; live</span></div> <div class="flow"> <div class="stage" data-s="0"><div class="n"><span class="lab">01 &middot; Onboard</span></div><h4>Drop in a board</h4><div class="board" id="boardMap"><span class="board-lbl">HWY 2 &amp; 21ST AVE E &middot; 14&times;48</span></div><div class="kv"><div><span>Coordinates</span><b>47.47, &minus;94.86</b></div><div><span>Facing</span><b>Eastbound</b></div><div><span>Market</span><b>Bemidji, MN</b></div></div></div> <div class="stage" data-s="1"><div class="n"><span class="lab">02 &middot; Analyze</span></div><h4>Read its DNA</h4><div class="layers"><span>Traffic</span><span data-c="demo">Demographics</span><span>Anchors nearby</span><span data-c="season">Seasonality</span><span>Events</span><span>Commute</span><span data-c="tourism">Tourism</span><span data-c="weather">Weather</span><span>Spend</span><span>Competition</span><span>New openings</span><span>Schools</span></div><div class="why">Every location layer fused into one profile of the place around the board.</div></div> <div class="stage" data-s="2"><div class="n"><span class="lab">03 &middot; Uncover</span></div><h4>Find the buyer</h4><div class="bars"><div class="bar"><div class="r"><b>Healthcare</b><span>92</span></div><div class="tr"><div class="fl" data-w="92"></div></div></div><div class="bar"><div class="r"><b>Powersports</b><span>84</span></div><div class="tr"><div class="fl" data-w="84"></div></div></div><div class="bar"><div class="r"><b>Hotels</b><span>77</span></div><div class="tr"><div class="fl" data-w="77"></div></div></div></div><div class="why"><b style="color:var(--ink2)">Why healthcare, Fall 2026:</b> the medical district is nearby, and flu-shot season and open enrollment both fall in the season.</div></div> <div class="stage" data-s="3"><div class="n"><span class="lab">04 &middot; Pitch</span></div><h4>Send the story</h4><div class="mail"><div class="to">To: Marketing lead &middot; Northpine Health</div><div class="typed" id="typed"></div></div><span class="send">Export &rarr;</span></div> </div> </div> </div> </div> <!-- TWO JOBS --> <section> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">One suite, two jobs</span><h2 style="margin-top:14px">Sell more of OOH. Bring more brands to OOH.</h2></div><p>Most operators compete for the same advertisers. doohthis helps your team find net-new customers that no one is pitching to, and gives you everything you need to reach out and close: personalised outreach, verified contact data and custom proposals, all built around why that business belongs on your board.</p></div> <div class="duo"> <div class="c" data-r="l"><span class="lab">For your sellers</span><h3>AI research and drafting support for every rep.</h3><p>doohthis handles the research, the ranking and the first draft, so reps can focus on the conversation.</p><ul><li>The right buyer for every face, every month</li><li>A pitch built on a real reason, at the right length for the reader</li><li>Every call, form and RFP answered with a matched proposal</li><li>Check-ins and upsells that arrive right on time</li></ul></div> <div class="c dk" data-r="rr"><span class="lab">For the medium</span><h3>Advertisers who never thought billboards were for them.</h3><p>The clinic, the dealership, the lake resort, the new café. doohthis finds these businesses and explains how out-of-home can work for them.</p><ul><li>Spots local businesses that fit your boards but have never run one</li><li>Explains the medium in plain words, with a campaign idea and ad mockup created for their business</li><li>Turns a first flight into a repeat account</li></ul></div> </div> </div> </section> <!-- PROBLEM --> <section class="prob"> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">The problem</span><h2 style="margin-top:14px">OOH sales still runs on guesswork.</h2></div><p>Reps spend hours researching brands and writing pitches by hand, with little time left to tailor each one. Inbound buyers go cold waiting for a rate card. Booked accounts often go quiet, which makes renewals harder to predict.</p></div> <div class="ba"> <div class="c tilt" data-r="l"><div class="lab">Before doohthis</div><ul><li><i>&times;</i>Hours of manual research for every pitch</li><li><i>&times;</i>Generic outreach with no real hook</li><li><i>&times;</i>Slow replies and one-size rate cards for inbound</li><li><i>&times;</i>Silent accounts churn silently</li></ul></div> <div class="c after tilt" data-r="rr"><div class="lab">With doohthis</div><ul><li><i>&check;</i>A real reason to reach out, built from what’s happening near the board</li><li><i>&check;</i>The exact brands to pitch, ranked, with the reason they belong there</li><li><i>&check;</i>Every inquiry qualified and matched to the right boards in minutes</li><li><i>&check;</i>Check-ins and upsells that surface at the right moment</li></ul></div> </div> </div> </section> <!-- PILLARS --> <section id="pillars"> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">The revenue engine</span><h2 style="margin-top:14px">Three pillars. One platform.</h2></div><p>doohthis powers every stage of the revenue cycle, finding new buyers, converting the ones who find you, and growing every account you’ve already won.</p></div> <div class="tabs" role="tablist"><button class="on" data-t="out">Outbound</button><button data-t="in">Inbound</button><button data-t="grow">Grow</button></div> <div class="pill on" data-p="out"> <div class="intro"><span class="lab">Outbound &middot; Stop waiting. Start targeting.</span><h3 style="margin-top:14px">Pitch the right buyer, at the right moment, with a story they can’t ignore.</h3><p>doohthis reads every board’s DNA, identifies the verticals and brands most likely to buy, and writes a personalised narrative around what’s happening near the board, so that even a regional gym or a new café chain has a reason to reply.</p><span class="tag">20%+ yield improvement</span><br><a class="btn btn-v" href="/outbound">Explore Outbound &rarr;</a></div> <div class="steps"><div class="s"><span class="k">01</span><div><h4>Onboard</h4><p>Add every board you own, static, digital, transit and street furniture.</p></div></div><div class="s"><span class="k">02</span><div><h4>Analyze <span>CORE ENGINE</span></h4><p>doohthis understands what’s around each board, who sees it, and what season it is.</p></div></div><div class="s"><span class="k">03</span><div><h4>Uncover</h4><p>It identifies the right verticals, the specific brands, and a clear reason why the board fits each one.</p></div></div><div class="s"><span class="k">04</span><div><h4>Pitch</h4><p>Send pitch packages, proposals and first emails directly to your CRM or outreach tool in one click.</p></div></div></div> </div> <div class="pill" data-p="in"> <div class="intro"><span class="lab">Inbound &middot; Stop missing leads. Start converting them.</span><h3 style="margin-top:14px">Every inquiry answered, matched and proposed, while interest is hot.</h3><p>Web forms, phone calls and RFP emails are captured, qualified and matched to the right boards automatically. Your rep reviews a tailored proposal and sends it in minutes, not days.</p><span class="tag">Always-on selling</span><br><a class="btn btn-v" href="/inbound">Explore Inbound &rarr;</a></div> <div class="steps"><div class="s"><span class="k">01</span><div><h4>Capture</h4><p>Every web form, call or RFP email is captured and routed instantly.</p></div></div><div class="s"><span class="k">02</span><div><h4>Qualify <span>CORE ENGINE</span></h4><p>AI scores the lead, category, budget signals and timeline, before a human touches it.</p></div></div><div class="s"><span class="k">03</span><div><h4>Match</h4><p>The right boards surface automatically, matched to audience, geography and goals.</p></div></div><div class="s"><span class="k">04</span><div><h4>Convert</h4><p>A tailored proposal is drafted. Your rep reviews, sends and closes.</p></div></div></div> </div> <div class="pill" data-p="grow"> <div class="intro"><span class="lab">Grow &middot; Stop losing accounts. Start compounding.</span><h3 style="margin-top:14px">Stay present through the whole contract, and grow it.</h3><p>Live signals from your boards, audience shifts, seasonal peaks, market events, trigger the right check-in or upsell at exactly the right time, and flag at-risk accounts before they go quiet.</p><span class="tag">Zero silent churn</span><br><a class="btn btn-v" href="/grow">Explore Grow &rarr;</a></div> <div class="steps"><div class="s"><span class="k">01</span><div><h4>Monitor</h4><p>Every live campaign is tracked, including audience, seasonal shifts and market signals.</p></div></div><div class="s"><span class="k">02</span><div><h4>Signal <span>CORE ENGINE</span></h4><p>Changes such as a traffic spike, a competitor vacancy or a seasonal window are flagged when they matter.</p></div></div><div class="s"><span class="k">03</span><div><h4>Engage</h4><p>Structured check-ins keep your rep consultative throughout the contract.</p></div></div><div class="s"><span class="k">04</span><div><h4>Expand</h4><p>Upsell moments arrive with context and a ready-to-send message.</p></div></div></div> </div> </div> </section> <!-- DNA --> <section class="dna"> <div class="mesh"></div> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">Board DNA</span><h2 style="margin-top:14px">Location intelligence, fused with buyer intent.</h2></div><p>Most tools tell you how many people pass a board. doohthis tells you who should be on it, by fusing what’s true about the place with what’s happening at the brands that want to reach it.</p></div> <div class="fuse fuse-map"> <div class="col tilt" data-r="l"><div class="ct">Location intelligence</div><p class="cs">What’s true about the place around the board.</p><div class="chips"><span data-c="traffic">Transit &amp; traffic</span><span data-c="demo">Demographics</span><span data-c="anchors">Nearby anchors</span><span data-c="season">Seasonality</span><span data-c="events">Local events</span><span data-c="tourism">Tourism</span><span data-c="weather">Weather</span><span>&hellip;</span></div></div> <div class="wf" id="core"> <div class="wf-steps"><button data-i="0"><b>1</b>Board</button><button data-i="1"><b>2</b>Season</button><button data-i="2"><b>3</b>Verticals</button><button data-i="3"><b>4</b>Business</button><button data-i="4"><b>5</b>Write-up</button><span class="wf-prog"><i></i></span></div> <div class="wf-map"><div id="wfMap"></div><div class="wf-pin"><span class="r"></span><span class="r r2"></span><span class="c"></span></div><div class="wf-chip"><b>Hwy 2 &amp; 21st Ave E</b><span>Bemidji, MN &middot; 14&times;48 static</span></div></div> <div class="wf-body"> <div class="wf-p" data-p="0"><span class="k">Board selected</span><div class="wf-kv"><div><span>Format</span><b>Static bulletin</b></div><div><span>Size</span><b>14 &times; 48 ft</b></div><div><span>Market</span><b>Bemidji, MN</b></div><div><span>Status</span><b class="ok">Available</b></div></div></div> <div class="wf-p" data-p="1"><span class="k">Season &middot; pick the season to sell</span><div class="wf-cal"><span class="on">Fall 2026</span><span>Winter 26&ndash;27</span><span>Spring 2027</span><span>Summer 2027</span></div><div class="wf-rng"><b>Fall 2026</b><span>Verticals are ranked for this season</span></div></div> <div class="wf-p" data-p="2"><span class="k">Top verticals &middot; Fall 2026</span><div class="wf-rk"><div class="sel"><span class="wf-ring" style="--v:92"><s>92</s></span><b>Healthcare</b><em>Top fit</em></div><div class=""><span class="wf-ring" style="--v:86"><s>86</s></span><b>Powersports</b><em></em></div><div class=""><span class="wf-ring" style="--v:79"><s>79</s></span><b>Education</b><em></em></div><div class=""><span class="wf-ring" style="--v:74"><s>74</s></span><b>QSR</b><em></em></div></div><div class="wf-why"><span>Why healthcare</span>The medical district is nearby, and flu-shot season and open enrollment both fall in the season.</div></div> <div class="wf-p" data-p="3"><span class="k">Healthcare &middot; businesses that fit &middot; contacts included</span><div class="wf-biz"><div class="sel"><span class="av">S</span><b>Northpine Health</b><em>Regional</em><span class="ck">&check;</span></div><div class=""><span class="av">E</span><b>Essentia Health</b><em>Regional</em></div><div class=""><span class="av">C</span><b>CVS Pharmacy</b><em>National</em></div><div class=""><span class="av">N</span><b>North Country Dental</b><em>Local</em></div></div></div> <div class="wf-p" data-p="4"><span class="k">Write-up &middot; Northpine Health &middot; Healthcare</span><div class="wf-mail"><div class="to">To: Dana Whitfield, Marketing</div><div id="wfType"></div></div></div> </div></div> <div class="col tilt" data-r="rr"><div class="ct">Firmographic intelligence</div><p class="cs">What’s happening at the brands that want to reach it.</p><div class="chips"><span data-c="open">Store openings</span><span data-c="expand">Expansion</span><span data-c="hiring">Hiring</span><span data-c="launch">Launches</span><span data-c="spons">Sponsorships</span><span data-c="rev">Revenue &amp; headcount</span><span>&hellip;</span></div></div> </div> <div class="outs"><div><b>Who to sell</b><span>Verticals and brands ranked for each board, national and local.</span></div><div><b>When</b><span>The season and the buyer’s own calendar, month by month.</span></div><div><b>Why</b><span>The reason the board fits, written into every pitch.</span></div></div><div class="ytd"><div class="ytw" data-r=""><div class="yt" data-id="hKMO1F4Rdo8" role="button" tabindex="0" aria-label="Play: Board DNA, explained"><img src="https://i.ytimg.com/vi/hKMO1F4Rdo8/maxresdefault.jpg" alt="" loading="lazy"><span class="yt-p"></span></div><div class="yt-c"><span class="lab">Watch</span><b>Board DNA, explained</b><span>How doohthis reads a board and ranks the verticals that fit each season.</span></div></div></div> </div> </section> <!-- SEASONALITY --> <section id="when" class="sea"> <div class="mesh"></div> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">Seasonality</span><h2 style="margin-top:14px">The best buyer for a board changes every month.</h2></div><p>Every board is affected by two calendars at once. doohthis reads both and re-ranks who should be on the board for any month you pick, the beer brand before kickoff, the snowmobile dealer before the first snow, the lake resort before Memorial Day.</p></div> <div class="cal"><div data-r="l"><b><i style="background:#7FB6E8"></i>The local calendar</b><p>Everything the market lives by: the weather, the sports seasons, the school year, holidays, festivals and tourist weekends. Football season moves beer and wings; lake season moves resorts; the first snow moves sleds.</p></div><div data-r="rr"><b><i style="background:#FEB34B"></i>The buyer’s own calendar</b><p>Every business has its own cycle: tax season, open enrollment, back to school, year-end sales, the holidays. The pitch is most effective when it arrives at the same time as their budget.</p></div></div> <div data-r=""><div class="sw" id="sw" data-m="0" data-scroll="1"><div class="mo"></div><div class="bd one"><div class="top4"></div></div></div></div> <p style="margin-top:14px;font-size:13px;color:rgba(255,255,255,.5)">Example board: Hwy 2 &amp; 21st Ave E, Bemidji, MN. Scroll to move through the year, or pick a month.</p> </div> </section> <!-- OUTCOMES --> <section> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">What you unlock</span><h2 style="margin-top:14px">Win more. Sell smarter. Own your market.</h2></div><p>These advantages build on each other and help your inventory generate revenue across the full sales cycle.</p></div> <div class="grid3"> <div class="o"><span class="lab">Outbound</span><h4>Higher yield</h4><p>Reach brands willing to pay premium rates for a relevant location, instead of relying on discounted defaults.</p><span class="stat">20%+ yield improvement</span></div> <div class="o"><span class="lab">Outbound</span><h4>Shorter sales cycles</h4><p>Replace “Does this board work?” with “Here’s why it’s perfect for your Q4 launch.”</p><span class="stat">Insight-driven narratives</span></div> <div class="o"><span class="lab">Outbound</span><h4>Empowered teams</h4><p>Every rep gets data-backed talking points, which supports confident and consultative selling instead of guesswork.</p><span class="stat">Auto-generated campaigns</span></div> <div class="o"><span class="lab">Inbound</span><h4>Instant RFP response</h4><p>AI drafts responses that are qualified, matched to your inventory and ready to send in seconds.</p><span class="stat">Always-on selling</span></div> <div class="o"><span class="lab">Inbound</span><h4>Sell 24/7</h4><p>An AI calling agent answers inbound calls with live board intelligence, so every call can be handled as a qualified sales conversation.</p><span class="stat">Real-time board intelligence</span></div> <div class="o"><span class="lab">Grow</span><h4>At-risk early warning</h4><p>Catch issues that could affect results and offer alternatives before performance suffers.</p><span class="stat">Zero silent churn</span></div> </div> </div> </section> <!-- BLOG --> <section style="padding-top:0"> <div class="wrap"> <div class="head"><div><div class="rule"></div><span class="lab">From the boardroom</span><h2 style="margin-top:14px">Notes on where OOH selling goes next.</h2></div><p><a class="btn btn-o" href="/blog">All posts &rarr;</a></p></div> <div class="posts"> <a class="post" href="/blog/why-every-ooh-sale-is-five-sales"><div class="art" style="background:url(/assets/blog/sponsorship.webp) center/cover"><span>EVENTS</span></div><div class="b"><span class="lab">Oct 14, 2026 &middot; 10 min</span><h4>Why every OOH sale is really five sales</h4><p>Our Gold Sponsor keynote at Apparatix Unleashed, and why no platform could automate the cases that matter.</p><span class="more">Read &rarr;</span></div></a> <a class="post" href="/blog/where-selling-goes-next"><div class="art" style="background:url(/assets/blog/future-ooh-sales.webp) center/cover"><span>SALES</span></div><div class="b"><span class="lab">Aug 10, 2026 &middot; 14 min</span><h4>The newest person on your team is showing you where selling goes next</h4><p>New AEs are building their own AI-assisted workflows. Here’s what they built, and where it comes apart.</p><span class="more">Read &rarr;</span></div></a> <a class="post" href="/blog/three-jobs-for-software"><div class="art" style="background:url(/assets/blog/before.webp) center/cover"><span>OPERATIONS</span></div><div class="b"><span class="lab">Jun 29, 2026 &middot; 12 min</span><h4>Three jobs for software before you hire your first AE</h4><p>Still the primary salesperson at your OOH company? Hand these three jobs to software first.</p><span class="more">Read &rarr;</span></div></a> </div> </div> </section> <!-- CTA --> <div class="cta"><div class="wrap"><div class="box" id="ctabox"><div class="mesh"></div><span class="lab" style="color:#C9BCF0">Sell smarter</span><h2 style="margin-top:14px">Every board has its story, and its buyer, for every moment.</h2><p>Outbound, Inbound and Grow, one AI sales suite for independent OOH operators and regional media companies.</p><div class="ctas"><a class="btn btn-w" href="/book-demo">Book a demo &rarr;</a><a class="btn btn-g" href="/how-it-works">See how it works</a></div></div></div></div> <footer><div class="wrap"><div class="fgrid"><div><a class="logo" href="/">doohthis</a><p>The AI sales suite for out-of-home. Sell every board you own, and bring advertisers into OOH who never thought it was for them.</p></div><div><h5>Product</h5><ul><li><a href="/how-it-works">How it works</a></li><li><a href="/outbound">Outbound</a></li><li><a href="/inbound">Inbound</a></li><li><a href="/grow">Grow</a></li><li><a href="/faq">FAQ</a></li></ul></div><div><h5>Company</h5><ul><li><a href="/about">About us</a></li><li><a href="/blog">Blog</a></li><li><a href="/news">News</a></li><li><a href="/book-demo">Book a demo</a></li><li></li></ul></div><div><h5>Legal</h5><ul><li><a href="/privacy">Privacy Policy</a></li><li><a href="/terms">Terms of Service</a></li><li><a href="/acceptable-use">Acceptable Use Policy</a></li><li><a href="/cookies">Cookie Policy</a></li></ul></div></div><div class="fbot"><span>&copy; 2026 doohthis Inc. Delaware C Corp. All rights reserved.</span><div class="mem"><a href="https://oaaa.org/" class="oaaa"><span>Member</span><img src="/assets/logo-oaaa.png" alt="OAAA member"></a><a href="https://www.geopath.org"><img src="/assets/logo-geopath-white.png" alt="Geopath"></a></div><div class="soc"><a href="https://www.linkedin.com/company/doohthis/" aria-label="doohthis on LinkedIn" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M20.45 20.45h-3.55v-5.57c0-1.33-.03-3.04-1.85-3.04-1.86 0-2.14 1.45-2.14 2.94v5.67H9.36V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12ZM7.12 20.45H3.56V9h3.56v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.73v20.54C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.73V1.73C24 .77 23.2 0 22.22 0Z"/></svg></a><a href="https://www.instagram.com/doohthis/" aria-label="doohthis on Instagram" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"/></svg></a><a href="https://x.com/doohthis" aria-label="doohthis on X" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M17.75 3h3.07l-6.7 7.66L22 21h-6.17l-4.83-6.32L5.47 21H2.4l7.17-8.2L2 3h6.33l4.37 5.77L17.75 3Zm-1.08 16.17h1.7L7.4 4.74H5.58l11.09 14.43Z"/></svg></a></div></div><p class="geo">The Geopath Audience Location Measurement&#8480; data is provided by Geopath, Inc., New York, New York. &copy; Copyright 2026, All Rights Reserved.</p></div></footer> <script> const nav=document.getElementById('nav');addEventListener('scroll',()=>nav.classList.toggle('solid',scrollY>40),{passive:true}); const tabs=[...document.querySelectorAll('.tabs button')],pills=[...document.querySelectorAll('.pill')]; const show=t=>{tabs.forEach(b=>b.classList.toggle('on',b.dataset.t===t));pills.forEach(p=>p.classList.toggle('on',p.dataset.p===t));}; tabs.forEach(b=>b.onclick=()=>show(b.dataset.t)); // engine demo loop const stages=[...document.querySelectorAll('.stage')],typed=document.getElementById('typed'); const msg="Hi Dana, flu-shot season and open enrollment both land in October and November, and our Hwy 2 & 21st Ave E board sits on the main road into Bemidji’s medical district. Can I send you a mockup with Northpine on it?"; const layers=[...stages[1].querySelectorAll('.layers span')],fills=[...document.querySelectorAll('.fl')]; let tt,step=0; function run(){ const s=step%5; stages.forEach((el,i)=>el.classList.toggle('on',i<=s&&s<4||s===4)); if(s===0){layers.forEach(l=>l.classList.remove('hit'));fills.forEach(f=>f.style.width='0');clearInterval(tt);typed.textContent='';} if(s===1)layers.forEach((l,i)=>setTimeout(()=>l.classList.add('hit'),i*110)); if(s===2)fills.forEach(f=>f.style.width=f.dataset.w+'%'); if(s===3){let i=0;clearInterval(tt);tt=setInterval(()=>{typed.textContent=msg.slice(0,++i);if(i>=msg.length)clearInterval(tt);},22);} step++; setTimeout(run, s===3?5200:s===4?2600:2200); } if(matchMedia('(prefers-reduced-motion: reduce)').matches){stages.forEach(s=>s.classList.add('on'));layers.forEach(l=>l.classList.add('hit'));fills.forEach(f=>f.style.width=f.dataset.w+'%');typed.textContent=msg;}else run(); // ── scroll 3D ── const RM=matchMedia('(prefers-reduced-motion: reduce)').matches; document.querySelectorAll('.head').forEach(h=>h.setAttribute('data-r','')); document.querySelectorAll('.grid3 .o,.posts .post,.steps .s,.outs>div').forEach((el,i)=>{el.setAttribute('data-r','');el.style.transitionDelay=(i%6)*70+'ms';}); const io=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}}),{threshold:.18,rootMargin:'0px 0px -6% 0px'}); document.querySelectorAll('[data-r]').forEach(el=>RM?el.classList.add('in'):io.observe(el)); const demo=document.querySelector('.demo'),hh1=document.querySelector('.hero h1'),core=document.getElementById('core'),cta=document.getElementById('ctabox'),meshes=[...document.querySelectorAll('.mesh')]; const cl=(v,a,b)=>Math.max(a,Math.min(b,v)); function frame(){ const vh=innerHeight,y=scrollY; // hero demo: tilted back, flattens as you scroll into it const dr=demo.getBoundingClientRect(),p=cl(1-(dr.top-vh*.25)/(vh*.75),0,1); demo.style.transform=`rotateX(${(1-p)*24}deg) scale(${.9+p*.1}) translateZ(0)`; stages.forEach((s,i)=>{s.style.transform=s.classList.contains('on')?`translateZ(${(1-p)*(i-1.5)*40}px)`:'translateY(8px)';}); hh1.style.transform=`translate3d(0,${y*.18}px,0)`;hh1.style.opacity=cl(1-y/700,0,1); meshes.forEach(m=>{const r=m.parentElement.getBoundingClientRect();m.style.translate=`0 ${(r.top)*-.12}px`;}); // DNA core: spins and rises const cr=core.getBoundingClientRect(),cp=cl(1-(cr.top-vh*.2)/(vh*.6),0,1); core.style.transform=`perspective(1400px) rotateX(${(1-cp)*16}deg) scale(${.94+cp*.06})`; // CTA box: lifts up from flat const br=cta.getBoundingClientRect(),bp=cl(1-(br.top-vh*.2)/(vh*.8),0,1); cta.style.transform=`perspective(1400px) rotateX(${(1-bp)*-28}deg) translateY(${(1-bp)*60}px) scale(${.92+bp*.08})`; ticking=false; } let ticking=false; if(!RM){addEventListener('scroll',()=>{if(!ticking){ticking=true;requestAnimationFrame(frame);}},{passive:true});addEventListener('resize',frame);frame();} // pointer tilt on cards if(!RM&&matchMedia('(hover:hover)').matches)document.querySelectorAll('.tilt,.post,.grid3 .o').forEach(el=>{ el.addEventListener('mousemove',e=>{if(!el.classList.contains('in')&&el.hasAttribute('data-r'))return;const r=el.getBoundingClientRect(),x=(e.clientX-r.left)/r.width-.5,yy=(e.clientY-r.top)/r.height-.5;el.style.transition='transform .1s';el.style.transform=`perspective(900px) rotateY(${x*8}deg) rotateX(${-yy*8}deg) translateZ(6px)`;}); el.addEventListener('mouseleave',()=>{el.style.transition='transform .5s';el.style.transform='';}); }); (function(){ const M=['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; const V=[ ['Tax preparation',30,[[0,3,95,'c','Filing season, three tax offices on the retail strip nearby']]], ['Fitness & gyms',34,[[0,0,93,'c','New Year resolutions, the year’s biggest sign-up month'],[8,8,78,'c','Back-to-routine after summer']]], ['Wedding & bridal',28,[[1,1,86,'c','Engagement season peaks after the holidays, couples book now for summer']]], ['Snowmobiles & powersports',32,[[10,1,90,'s','Trail season, weekend riders head out on Hwy 2'],[4,5,80,'s','Boats and ATVs as the ice goes out']]], ['Beer & sports bars',34,[[8,0,91,'s','Football season, Vikings Sundays and BSU home games'],[2,2,84,'s','March Madness and the state hockey tournament']]], ['Auto dealers',38,[[2,3,85,'c','Tax refunds land, dealers nearby along Hwy 2'],[11,11,86,'c','Year-end sales events']]], ['Landscaping & garden',24,[[3,5,90,'s','Spring thaw, single-family homes around the board']]], ['Real estate & mortgage',32,[[3,5,88,'c','Spring buying season, listings and showings peak']]], ['Hotels & lake tourism',30,[[5,7,94,'s','Lake season and the Fourth of July, weekend visitors on Hwy 2']]], ['Fireworks & summer events',18,[[5,6,92,'s','Fourth of July week, tents and town festivals']]], ['Back to school retail',26,[[7,7,93,'c','Supply lists, clothes and dorm move-in']]], ['Education & enrollment',30,[[1,2,82,'c','Bemidji State enrollment decisions, campus nearby'],[7,7,80,'c','BSU move-in week']]], ['Hunting & outdoor',24,[[9,10,92,'s','Deer opener in November, gear up in October']]], ['Healthcare',40,[[9,10,92,'c','Flu shots and open enrollment, medical district nearby']]], ['Medicare plans',22,[[9,11,89,'c','Medicare open enrollment, Oct 15 – Dec 7']]], ['HVAC & home services',32,[[5,6,82,'s','Summer heat, older housing stock nearby'],[10,10,87,'s','Furnace season, first sub-zero nights']]], ['Retail & holiday',36,[[10,11,94,'c','Holiday run to the Paul Bunyan Dr retail strip']]], ['Florists & gifts',20,[[1,1,88,'c','Valentine’s Day'],[4,4,86,'c','Mother’s Day']]]]; const inW=(m,a,b)=>a<=b?(m>=a&&m<=b):(m>=a||m<=b); const sc=(v,m)=>{let best=[v[1],null];v[2].forEach(w=>{let s=0;if(inW(m,w[0],w[1]))s=w[2];else if(inW((m+1)%12,w[0],w[1])||inW((m+11)%12,w[0],w[1]))s=w[2]-22;if(s>best[0])best=[s,w];});return best;}; const SC='#7FB6E8',CC='#FEB34B'; document.querySelectorAll('.sw').forEach(root=>{ const mo=root.querySelector('.mo'),t4=root.querySelector('.top4'),hm=root.querySelector('.hm'); let cur=+(root.dataset.m||9),manual=false; mo.innerHTML=M.map((m,i)=>'<button data-i="'+i+'">'+m+'</button>').join(''); if(hm)hm.innerHTML='<div class="hr hhd"><span></span>'+M.map((m,i)=>'<span class="mh" data-i="'+i+'">'+m[0]+'</span>').join('')+'</div>'+V.map(v=>'<div class="hr" data-v="'+v[0]+'"><span class="vl">'+v[0]+'</span>'+M.map((_,i)=>{const [s,w]=sc(v,i),a=Math.max(0,(s-35)/60),col=w?(w[3]==='s'?'127,182,232':'254,179,75'):'255,255,255';return '<span class="c" data-i="'+i+'" title="'+v[0]+' · '+M[i]+' · '+s+'" style="background:rgba('+col+','+(w?.15+a*.85:.05+a*.1).toFixed(2)+')"></span>';}).join('')+'</div>').join(''); let prevRank={}; function set(m){cur=m;mo.querySelectorAll('button').forEach(b=>b.classList.toggle('on',+b.dataset.i===m));hm&&hm.querySelectorAll('[data-i]').forEach(c=>c.classList.toggle('cur',+c.dataset.i===m)); const ALL=V.map(v=>{const [s,w]=sc(v,m);return {n:v[0],s,w};}).sort((a,b)=>b.s-a.s);const pm=(m+11)%12,PR={};V.map(v=>({n:v[0],s:sc(v,pm)[0]})).sort((a,b)=>b.s-a.s).forEach((x,k)=>PR[x.n]=k);const L=ALL.slice(0,4); t4.innerHTML='<span class="lab" style="margin-bottom:2px">Best on this board in '+M[m].charAt(0)+M[m].slice(1).toLowerCase()+'</span>'+L.map((x,k)=>{const d=PR[x.n]-k,inw=x.w&&inW(m,x.w[0],x.w[1]),mv=d>0?'<span class="mv up">&#9650; '+d+' from '+M[pm].charAt(0)+M[pm].slice(1).toLowerCase()+'</span>':d<0?'<span class="mv dn">&#9660; '+(-d)+' from '+M[pm].charAt(0)+M[pm].slice(1).toLowerCase()+'</span>':'<span class="mv eq">Same as '+M[pm].charAt(0)+M[pm].slice(1).toLowerCase()+'</span>'; const src=x.w?(x.w[3]==='s'?'Local calendar':'Buyer’s own calendar'):'Baseline';const txt=x.w?(inw?x.w[4]:(inW((m+1)%12,x.w[0],x.w[1])?x.w[4]+', starts next month, so buyers plan now':x.w[4]+', just ended, so demand is still warm')):'Fits this board all year, no seasonal peak this month'; return '<div class="tv"><div class="r"><span class="tvr" style="--v:'+x.s+'"><s>'+x.s+'</s></span><b>'+x.n+'</b>'+mv+'</div><div class="why"><i style="background:'+(x.w?(x.w[3]==='s'?SC:CC):'rgba(255,255,255,.3)')+'"></i><span><em>'+src+'</em>'+txt+'</span></div></div>';}).join(''); requestAnimationFrame(()=>t4.querySelectorAll('.tvr').forEach(r=>r.classList.add('go')));} mo.addEventListener('click',e=>{const b=e.target.closest('button');if(!b)return;manual=true;set(+b.dataset.i);}); set(cur); if(root.dataset.scroll&&!matchMedia('(prefers-reduced-motion: reduce)').matches){const sec=root.closest('section');addEventListener('scroll',()=>{if(manual)return;const r=sec.getBoundingClientRect(),p=(innerHeight*.6-r.top)/(r.height);if(p<0||p>1)return;const m=Math.min(11,Math.max(0,Math.floor(p*14)-1));if(m!==cur)set(m);},{passive:true});} }); document.querySelectorAll('.gmap').forEach(g=>{const o=new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){g.classList.add('go');o.disconnect();}}),{threshold:.35});o.observe(g);}); })(); </script> <script src="/frontier.js"></script> <script> (function(){const wf=document.getElementById('core');if(!wf)return; const btns=[...wf.querySelectorAll('.wf-steps button')],ps=[...wf.querySelectorAll('.wf-p')],bar=wf.querySelector('.wf-prog i'),ty=document.getElementById('wfType'); const chips=[...document.querySelectorAll('.fuse [data-c]')],LIT={2:['anchors','season','demo','events'],3:['rev','expand','open']}; const MSG="Hi Dana, flu-shot season and open enrollment both land in October and November, and our Hwy 2 & 21st Ave E board sits on the main road into Bemidji’s medical district. Can I send you a mockup with Northpine on it?"; let cur=0,tm=null,tt=null; try{if(window.L){const m=L.map('wfMap',{zoomControl:false,attributionControl:true,dragging:false,scrollWheelZoom:false,doubleClickZoom:false,boxZoom:false,keyboard:false,touchZoom:false}).setView([47.4736,-94.8803],14);L.tileLayer('/api/carto/dark/{z}/{x}/{y}.png',{attribution:'&copy; OpenStreetMap &copy; CARTO',maxZoom:19}).addTo(m);m.attributionControl.setPrefix(false);wf.mapObj=m;}}catch(e){} function type(){clearInterval(tt);ty.textContent='';let n=0;tt=setInterval(()=>{ty.textContent=MSG.slice(0,++n);if(n>=MSG.length)clearInterval(tt);},18);} function show(n){cur=n;btns.forEach((b,x)=>{b.classList.toggle('on',x===n);b.classList.toggle('done',x<n);});ps.forEach((p,x)=>p.classList.toggle('on',x===n));bar.style.width=(n/4*100)+'%'; chips.forEach(c=>c.classList.toggle('lit',(LIT[n]||[]).includes(c.dataset.c))); if(wf.mapObj){wf.mapObj.flyTo([47.4736,-94.8803],n===0?15:n===2?13:14,{duration:1.2});} if(n===4)type();} function play(){clearInterval(tm);tm=setInterval(()=>show((cur+1)%5),cur===4?6500:3600);} btns.forEach(b=>b.onclick=()=>{show(+b.dataset.i);play();}); wf.addEventListener('mouseenter',()=>clearInterval(tm));wf.addEventListener('mouseleave',play); show(0);if(!matchMedia('(prefers-reduced-motion: reduce)').matches){new IntersectionObserver(es=>es.forEach(e=>{if(e.isIntersecting){play();wf.mapObj&&wf.mapObj.invalidateSize();}else clearInterval(tm);}),{threshold:.3}).observe(wf);} })(); </script> <script> (function(){try{ var el=document.getElementById('boardMap'); if(!el||!window.L)return; var lat=47.4736,lng=-94.8803; var bm=L.map('boardMap',{zoomControl:false,attributionControl:false,dragging:false,scrollWheelZoom:false,doubleClickZoom:false,boxZoom:false,keyboard:false,touchZoom:false,tap:false}).setView([lat,lng],14); L.tileLayer('/api/carto/dark/{z}/{x}/{y}.png',{maxZoom:19}).addTo(bm); L.circleMarker([lat,lng],{radius:6,color:'#FEB34B',weight:3,opacity:.45,fillColor:'#FEB34B',fillOpacity:1}).addTo(bm); new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting)setTimeout(function(){bm.invalidateSize();},60);});},{threshold:.1}).observe(el); }catch(e){}})(); </script> <div class="hx-modal" id="hx-modal" data-testid="hero-explainer-modal" aria-hidden="true"><div class="hx-box"><button type="button" class="hx-x" id="hx-close" data-testid="hero-explainer-close" aria-label="Close video">&times;</button><div class="hx-v" id="hx-v"></div></div></div> <style>.hx-btn{display:inline-flex;align-items:center;gap:10px;cursor:pointer;font:inherit}.hx-ic{width:22px;height:22px;border-radius:50%;background:#4A12A8;position:relative;flex:none;transition:transform .25s ease}.hx-ic::after{content:"";position:absolute;left:8px;top:6px;border-left:8px solid #fff;border-top:5px solid transparent;border-bottom:5px solid transparent}.hx-btn:hover .hx-ic{transform:scale(1.12)}.hx-modal{position:fixed;inset:0;z-index:9999;background:rgba(14,8,30,.72);backdrop-filter:blur(14px);display:flex;align-items:center;justify-content:center;padding:24px;opacity:0;pointer-events:none;transition:opacity .3s ease}.hx-modal.on{opacity:1;pointer-events:auto}.hx-box{position:relative;width:min(1100px,100%);transform:translateY(16px) scale(.98);transition:transform .35s ease}.hx-modal.on .hx-box{transform:none}.hx-v{aspect-ratio:16/9;border-radius:18px;overflow:hidden;background:#0F0A22;box-shadow:0 40px 120px rgba(0,0,0,.5)}.hx-v iframe{width:100%;height:100%;border:0;display:block}.hx-x{position:absolute;top:-48px;right:0;width:40px;height:40px;border-radius:50%;border:0;background:rgba(255,255,255,.14);color:#fff;font-size:24px;cursor:pointer;transition:background-color .2s ease}.hx-x:hover{background:rgba(255,255,255,.28)}</style> <script>(function(){var m=document.getElementById('hx-modal'),v=document.getElementById('hx-v');function open(){v.innerHTML='<iframe src="https://www.youtube-nocookie.com/embed/hKMO1F4Rdo8?autoplay=1&rel=0" title="Board DNA, explained" allow="autoplay; encrypted-media; picture-in-picture" allowfullscreen></iframe>';m.classList.add('on');m.setAttribute('aria-hidden','false')}function close(){m.classList.remove('on');m.setAttribute('aria-hidden','true');setTimeout(function(){v.innerHTML=''},300)}document.getElementById('hero-explainer-btn').addEventListener('click',open);document.getElementById('hx-close').addEventListener('click',close);m.addEventListener('click',function(e){if(e.target===m)close()});document.addEventListener('keydown',function(e){if(e.key==='Escape')close()})})();</script> </body> </html></plaintext><iframe id="li_sync_frame" title="data" src="https://i.liadm.com/sync-container?duid=7594cf95eefc--01m60ynbx9mdknm0ejd17cwn8n&amp;ds=did-0091&amp;euns=1&amp;s=&amp;version=v3.20.0&amp;cd=.doohthis.com&amp;pv=7a75730a-0e36-4b38-be72-85f2b8095882" style="opacity: 0; width: 0px; height: 0px; border: 0px; position: absolute; top: 0px; left: 0px; z-index: -1000;"></iframe></body></html>