Blog  /  Outbound

The photosheet is dead. Long live the photosheet.

The photosheet was infrastructure for a 1995 sales motion that operators have been running on autopilot for thirty years. The motion stopped working somewhere around 2018. Here’s what replaces it.

By Thiru Saravanan·May 19, 2026·9 min read
Long live the photosheet

Every OOH operator has a folder of photosheets. Most of them have several.

You know the ones. A one-page PDF for each board on the network. Photo of the structure in the upper left. Specs across the top: dimensions, illumination, build date, lat-long. Impressions from a study someone commissioned in 2017. A small map graphic showing the board's position relative to a freeway exit. And then — in the bottom third of the page, in slightly-too-small font — the talking points.

Excellent visibility from northbound traffic. Reaches commuters traveling from the suburbs into the central business district. High-income demographic. Strong fit for retail, automotive, and quick-service restaurants.

Nobody who works at the operator remembers who wrote those talking points. The file metadata says they were created in 2019 by someone whose name doesn't appear on the current org chart. Several of them describe nearby businesses that have since closed. One of them refers to a stadium the city tore down four years ago. The "high-income demographic" claim was made before the new apartment complex went up across the street and shifted the trade area's median income by twenty thousand dollars.

The photosheets are stale. The rep using them knows they're stale. The rep using them is using them anyway, because what's the alternative.

This piece is about the alternative.


What the photosheet was supposed to be

The photosheet, as an artifact, made sense in the world it was created for.

That world looked like this: an advertiser called the operator. The rep took the call. The rep needed to leave-behind something that proved the board existed, looked good, and was worth the money. Print the photosheet, fax the photosheet, eventually email the photosheet as a PDF. The advertiser glanced at it, filed it, and either called back or didn't.

In that world, the photosheet was a static artifact for a static conversation. The board didn't change. The talking points didn't need to change. The pitch was: here is what we have, here is roughly what it's near, here is the rate.

That world is gone.

The advertiser today is not asking what do you have. They are asking what is this specific board, for my specific business, this specific quarter. If you answer that question by emailing them a 2019 PDF with the rate handwritten in the margin, the conversation ends before the discount is even negotiated. Not because your board is wrong for them — it might be perfect for them — but because the artifact you sent told them you don't actually know what your board is.

The photosheet was infrastructure for a 1995 sales motion that operators have been running on autopilot for thirty years. The motion stopped working somewhere around 2018. The infrastructure is still in the folder.


What a board actually is, when you stop treating it as a poster

A board is not a static object. It is a position in a system that moves around it.

Take any single board on any operator's network. Stand in front of it. Look at what's actually there. The trade area shifted demographically in the last five years. The retail context changed — a Target opened two miles east, the regional mall lost its anchor tenant, the highway exit pattern got re-engineered when the new bypass went in. The audience flowing past changed because the route function changed — what used to be commuter traffic is now mixed commuter and event traffic because the arena opened. The seasonal pattern is different from what the 2019 photosheet captured because the local festival circuit doubled and the high school district consolidated.

The board didn't move. Everything around it did.

Now layer on what's happening to the brands and verticals that historically buy in this kind of context. QSR is in a discount-cycle pull because grocery inflation flipped consumer behavior. Auto is sitting on the highest inventory levels since 2008. Healthcare systems in the region are in active competitive expansion. The state tourism board just got a budget increase and is shopping for OOH in this exact corridor. Three regional banks are positioning for an M&A cycle and are about to spend on awareness.

None of that is in the photosheet. None of it can be. The photosheet was written once, by one person, against a snapshot of a market that has since moved on without it.

The board's real talking points — the ones that would actually win a pitch today — change every week. They are a function of who the board is for, this quarter, given everything happening around it. They are written for the specific vertical the rep is calling. They are sharpened further for the specific brand inside that vertical, given what that brand is currently doing.

A rep who has access to those talking points walks into a different conversation than the rep who has the photosheet.


Three layers of pitch the photosheet was never going to produce

When you stop treating a board as a poster and start treating it as a position in a system, the pitch decomposes into three layers — each one more specific than the last, each one impossible for a static document to capture.

The board layer. Why this specific board matters, framed against what's actually true about its corridor, audience, traffic patterns, seasonal density, format advantages, and contextual relevance — right now. Not in 2019. Not in averages. Now.

For a digital bulletin on the US-2 / MN-71 corridor in Cass Lake, the board layer talks about its position as a gateway to the Leech Lake region, its 9,800 daily impressions skewing toward resort travelers and seasonal cabin owners, the seasonal traffic surge from May through September during peak fishing and resort season, the ice fishing and snowmobile audience from December through March, the contextual proximity to Bemidji State University. Each of those is a defensible, specific, current claim about what makes that board what it is. None of them are in any photosheet anywhere.

Board-layer talking points for a single bulletin, generated fresh against current corridor and trade-area context. The rep no longer pulls these from memory or from a 2019 PDF.
Board-layer talking points for a single bulletin, generated fresh against current corridor and trade-area context. The rep no longer pulls these from memory or from a 2019 PDF.

The vertical layer. Why this board, for this category of advertiser. Same board, different lens. Each vertical has different audience requirements, different seasonal patterns, different messaging windows. A board that scores high for QSR scores differently for healthcare, differently again for tourism, differently for B2B. The pitch should reflect that.

For the same Cass Lake board scored against QSR, the vertical layer talks about the captive 15–30-minute exposure window, the audience's commuter overlap with QSR locations along the route, the morning and afternoon peaks aligning with QSR breakfast and lunch, the moment of food-decision-planning the ad intercepts, and the format's fit for value messaging and LTO promotions. That's a different pitch from the same board to a tourism brand or a healthcare system. The board didn't change. The lens did.

Vertical-layer fit scoring with explanation. The rep walks into a QSR pitch knowing the board scores 85 out of 100 and exactly why.
Vertical-layer fit scoring with explanation. The rep walks into a QSR pitch knowing the board scores 85 out of 100 and exactly why.

The brand layer. Why this board, for this specific brand, given what that brand is actually doing this quarter. Same board, same vertical, narrowed once more to the named advertiser. Their current campaign cycle. Their seasonal spend pattern. Their product launches. Their geographic expansion. Their competitive pressure points.

For the same Cass Lake board pitched to Discover Illinois, the brand layer doesn't talk about generic tourism. It talks about Discover Illinois's summer campaign window (May–Aug, their highest-spend OOH period), the fall color season they're actively investing in to extend the tourism cycle, the winter recreation economy worth $1.2B annually that their winter campaign targets, and the "Discover Your Backyard" staycation push aimed at families aged 30–55. The pitch lands not because the board is generically good for tourism — it lands because the rep walked into the conversation already knowing what Discover Illinois is doing this year, and showed them how this specific board fits.

Brand-layer pitch angle and story hooks for a specific advertiser, tied to that brand's current campaign cycle. Same board, different lens — and a sharper email to send Monday morning.
Brand-layer pitch angle and story hooks for a specific advertiser, tied to that brand's current campaign cycle. Same board, different lens — and a sharper email to send Monday morning.

Three layers. Each one a function of dynamic inputs that move on their own schedule. None of them produceable by a one-page PDF.


Why the rep keeps using the photosheet anyway

The honest reason the photosheet survives is not that anyone defends it. It survives because the alternative — researching the corridor freshly, scoring the vertical fit specifically, looking up the brand's current campaign and product news, and synthesizing all three into a coherent pitch — takes about ninety minutes per board per call.

A rep with a ten-board pitch and twenty prospects to call this week cannot do that work manually. So the rep does what humans always do when the task is impossible: they cut corners. They use the photosheet. They paste in the same three talking points they've been using since they joined the company. They send the proposal with the rate and a map and hope the relationship carries it across the line.

The relationship sometimes does carry it. The relationship is also why most operators have stopped noticing that their inbound conversion has been declining quarter over quarter for five years. The rep is still good at the relationship part. The artifact in their hand is letting them down on everything else.

The fix is not "tell the rep to work harder." Reps already work harder than the system gives them credit for. The fix is to put the three-layer pitch on demand — every board, every vertical, every brand, refreshed every week. The rep stops authoring. The rep starts editing and sending.

This is what Pitch Prep is.


What a rep's morning looks like when Pitch Prep is in the stack

The rep walks in. They have eight calls scheduled today, across a mix of inbound responders and outbound prospects. They open the system.

They click the first board on the map. The board layer talking points are already there — ten of them, current, written against everything happening in that corridor this month. They scan, they pick four, they internalize.

They type in the vertical the prospect operates in — QSR. The fit score appears: 85. The narrative is two sentences. The five key factors are bulleted. The rep knows now, before the call, that this board is a strong fit for this category and exactly why. They didn't have to guess.

They type in the brand: McDonald's. The brand layer renders. The pitch angle is one sentence. Four story hooks tied to McDonald's current campaign cycle, their seasonal moments, their product launches, their geographic priorities. The rep picks one or two that resonate.

The rep places the call. They open with the brand-specific story — I noticed you've been pushing the breakfast bundle in the regional ads through Q2; we have a board on a corridor where 9,800 commuters pass three of your locations every morning, and the May–July inventory we have aligns with that push. They are seventy seconds into the call and the prospect is leaning in.

Ninety minutes of pre-call research has become ninety seconds of pre-call review. The rep made ten of those calls today instead of two. The pitches were sharper, not generic. The pipeline moves.

That is the rep's morning when Pitch Prep is in the stack. The photosheet you have in the folder is still there. Nobody's opened it in months. But what the photosheet was always trying to be — current, board-by-board, specific to the buyer in front of the rep — is finally what's on the screen every morning.


doohthis builds Pitch Prep — the three-layer pitch generation system that replaces the photosheet with board-level, vertical-level, and brand-level talking points generated fresh, every time, against live inputs. If your reps are still copying bullets out of a 2019 PDF, 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--01m60yn2fq5xrnkd3jnhahj3x5&amp;ds=did-0091&amp;euns=1&amp;s=&amp;version=v3.20.0&amp;cd=.doohthis.com&amp;pv=1ba4b2c9-feb7-4781-a94a-5e39735fd4b6" style="opacity: 0; width: 0px; height: 0px; border: 0px; position: absolute; top: 0px; left: 0px; z-index: -1000;"></iframe></body></html>