'; } /* ============================================================ HERO SUCCESS HTML ============================================================ */ function getHeroSuccessHTML() { return '
' + '
Request received \u2014 you\'re in the queue
' + '

You\'re on your way to
winning more bids

' + '

WHAT HAPPENS NEXT

' + '
1

Check your inbox

A Joist AI specialist will be in touch shortly to confirm your request and next steps.

' + '
2

Discovery call to learn about you

We\'ll dig into your team\'s pursuit process, pain points, and goals before anything else.

' + '
3

Live demo tailored to your team

We\'ll show you exactly how Joist AI fits your firm \u2014 no generic walkthroughs, just what matters to you.

' + '
' + '' + '
'; } /* ============================================================ MODAL SUCCESS CLOSE BUTTON ============================================================ */ function bindSuccessCloseBtn() { setTimeout(function () { var btn = document.getElementById('joist-modal-success-close'); var overlay = document.querySelector('.overlay_wrap_2'); if (btn && overlay) { btn.addEventListener('click', function () { overlay.style.display = 'none'; }); } }, 50); } /* ============================================================ HERO SUCCESS HANDLER Hero submit → show page success + show modal success ============================================================ */ function handleHeroSuccess() { console.log('[JOIST COMMON] handleHeroSuccess called'); // 1. Show hero success on page var heroSection = document.querySelector('.hero-section'); console.log('[JOIST COMMON] .hero-section found:', !!heroSection); if (heroSection) { var splitLayout = heroSection.querySelector('.hero_split-layout'); if (splitLayout) splitLayout.style.display = 'none'; var heroCard = heroSection.querySelector('.hero_form-card'); if (heroCard) heroCard.style.display = 'none'; var heroFormDiv = document.getElementById('hubspot-demo-form'); if (heroFormDiv) heroFormDiv.style.display = 'none'; heroSection.insertAdjacentHTML('beforeend', getHeroSuccessHTML()); console.log('[JOIST COMMON] Hero success HTML injected into page'); window.scrollTo({ top: 0, behavior: 'smooth' }); } // 2. Also show modal success inside the modal handleModalSuccess(); } /* ============================================================ MODAL SUCCESS HANDLER Modal submit → show modal success only, page untouched ============================================================ */ function handleModalSuccess() { console.log('[JOIST COMMON] handleModalSuccess called'); var formDiv = document.getElementById('hubspot-modal-form'); console.log('[JOIST COMMON] #hubspot-modal-form found:', !!formDiv); if (!formDiv) return; var modalBody = formDiv.closest('.modal_form-body'); console.log('[JOIST COMMON] .modal_form-body found:', !!modalBody); if (!modalBody) return; var innerModalCard = modalBody.closest('.modal_form-card'); console.log('[JOIST COMMON] .modal_form-card found:', !!innerModalCard); if (!innerModalCard) return; // Guard: don't inject twice if (innerModalCard.querySelector('.modal-success-wrap')) { console.log('[JOIST COMMON] success already shown, skipping'); return; } var header = innerModalCard.querySelector('.modal_form-header'); var body = innerModalCard.querySelector('.modal_form-body'); if (header) header.style.display = 'none'; if (body) body.style.display = 'none'; innerModalCard.insertAdjacentHTML('beforeend', getModalSuccessHTML()); console.log('[JOIST COMMON] Modal success HTML injected'); bindSuccessCloseBtn(); requestAnimationFrame(function () { requestAnimationFrame(function () { var tick = innerModalCard.querySelector('.modal-success-tick-path'); if (tick) tick.style.strokeDashoffset = '0'; }); }); } /* ============================================================ SHARED ROUTER — called from BOTH form instances Since HubSpot fires onFormSubmitted unpredictably, ALL routing lives here in the common script. ============================================================ */ function onAnyFormSubmitted() { var which = window._joistActiveForm; console.log('[JOIST COMMON] onAnyFormSubmitted — _joistActiveForm:', which); window._joistActiveForm = null; if (which === 'hero') handleHeroSuccess(); else if (which === 'modal') handleModalSuccess(); else console.warn('[JOIST COMMON] onAnyFormSubmitted — unknown form, nothing to do'); } /* ============================================================ MODAL FORM INIT ============================================================ */ function initModalForm() { if (typeof hbspt === 'undefined') { setTimeout(initModalForm, 100); return; } if (!document.getElementById('hubspot-modal-form')) return; console.log('[JOIST COMMON] Creating modal HubSpot form'); hbspt.forms.create({ region: "na1", portalId: "8057448", formId: "a34c8ec9-1a72-41de-b9c0-6f36228b0ac2", target: "#hubspot-modal-form", css: "", onFormReady: function ($form) { console.log('[JOIST COMMON] modal onFormReady'); }, onFormSubmit: function ($form) { console.log('[JOIST COMMON] modal onFormSubmit — setting _joistActiveForm = modal'); window._joistActiveForm = 'modal'; var btn = $form.find('input[type="submit"]'); btn.val("Sending...").css({ opacity: "0.7", "pointer-events": "none", cursor: "not-allowed" }); }, onFormSubmitted: function () { console.log('[JOIST COMMON] modal onFormSubmitted fired'); onAnyFormSubmitted(); } }); } window.initJoistModalForm = initModalForm; initModalForm(); })();
Simplify proposal processes with AI
AI-Powered Proposals for AEC

Simplify proposal processes with AI

Simplify team collaboration proposal processes team collaboration win strategies with AI

Joist AI helps AEC firms find, curate and organize content so you and your team can create high quality, winning proposals with ease.
200+
AEC teams
$2.4B+
proposals submitted
50%
less prep time

Trusted by Leading AEC Firms

McKim & Creed - Joist AI ClientMcCarthy Logo - Joist AI client
why joist ai
Win More Work with Less Effort

As an AEC marketer, you and your team spend too much time searching through past projects and proposals. Joist AI is a pursuit enablement platform built for construction, architecture and engineering — automating proposal workflows so marketing teams can focus on strategy.

01
Quickly find the right content when you need it the most
02
Customize content to be strategic and compliant
03
Spend more time on the capture plan and win strategy
04
Collaborate with team members
Aa
05
Digitize writing style guide to automate compliance
RFx Checklist ! 14/14 met ✓
06
Compare against RFx requirements
Product Explainer
Your Next Winning Proposal Starts Here

Joist AI gives AEC teams the content, tools, and AI to win more work without the heavylifting.

Instant RFP parsing and requirement extraction
AI-matched past projects and team members
Live collaborative drafting workspace
Personal Proposal Assistant
Your AI teammate for every bid
Everything your proposal team needs to find content, draft faster, and win more — all in one place.
01
Advanced Search
No more digging through folders, servers, or databases — or waiting on team members
02
Generate new content
based on your own previous winning proposals and institutional knowledge.
03
Generate a Proposal Plan
with a click of a button by uploading RFQ/P, with the ability to edit from there.
04
A built-in analytics tool
helps you and your team catch language issues, duplications, and  inconsistencies.

Testimonials

Real Users. Real Results
"

Our team uses Joist AI every day. I can't imagine leading a proposal without it.

Ken Erickson
Senior Proposal Specialist · Mortenson
"

Joist AI allows us to show up differently in the proposal process—not just as information gatherers, but as strategists.

Jen Orthaus
Proposal Manager · Mortenson
"

If we tried to get rid of Joist AI now, we'd have a revolt. Our team members love it and rely on it daily.

Katy Klaproth
VP of Marketing & Comms · Robins & Morton

Latest from Joist AI

Making Headlines

Stay in-the-know with Joist AI happenings, news and events

Ready to Build Proposals Together?
Try Joist AI's platform and explore features and use cases that marketing teams love.
Book a Demo