蜜桃传媒

Customer Development Agreement Template for Ireland

A comprehensive legal agreement governed by Irish law that establishes the terms and conditions under which a service provider will develop custom software, technology solutions, or digital products for a customer. The agreement covers essential aspects including project scope, methodology, deliverables, intellectual property rights, testing procedures, and acceptance criteria, while ensuring compliance with Irish contract law, data protection regulations, and consumer protection requirements. It provides a structured framework for managing the development process, defining responsibilities, and protecting both parties' interests throughout the project lifecycle.

Typically:
i
This cost is based on prices provided by
6 legal services in your market.
With 蜜桃传媒AI:

拢0

i
Generate and export your first
document completely free.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Get template free

Your data doesn't train 蜜桃传媒's AI

You keep IP ownership聽of your docs

4.6 / 5
4.6 / 5
4.8 / 5
Alternatively...

What is a Customer Development Agreement?

The Customer Development Agreement is essential for businesses engaging in custom software or technology development projects in Ireland. This contract type establishes the legal framework for development services, ensuring compliance with Irish contract law, GDPR, and relevant EU regulations. It is typically used when a customer requires bespoke development work, whether for software applications, technology solutions, or digital products. The agreement comprehensively covers project specifications, development methodology, acceptance criteria, intellectual property rights, and payment terms. It's particularly important in the Irish market where technology development services are a significant sector, and where both domestic and international companies need to ensure their development agreements align with local legal requirements and EU regulations. The document provides necessary protections for both the service provider and the customer while facilitating clear project governance and risk management.

What sections should be included in a Customer Development Agreement?

1. Parties: Identification and details of the contracting parties

2. Background: Context of the agreement and high-level objectives

3. Definitions: Defined terms used throughout the agreement

4. Scope of Services: Detailed description of development services to be provided

5. Project Methodology: Development approach, methodologies, and project management procedures

6. Customer Obligations: Requirements and responsibilities of the customer

7. Developer Obligations: Requirements and responsibilities of the developer

8. Deliverables: Specific outputs and acceptance criteria

9. Testing and Acceptance: Procedures for testing deliverables and acceptance criteria

10. Change Control: Process for managing changes to scope or requirements

11. Intellectual Property Rights: Ownership and licensing of developed materials

12. Payment Terms: Fees, payment schedule, and invoicing procedures

13. Data Protection: GDPR compliance and data handling requirements

14. Confidentiality: Protection of confidential information

15. Term and Termination: Duration and termination provisions

16. Warranties and Indemnities: Guarantees and protections provided by each party

17. Limitation of Liability: Caps and exclusions on liability

18. Force Majeure: Provisions for unforeseen circumstances

19. General Provisions: Standard boilerplate clauses including governing law

What sections are optional to include in a Customer Development Agreement?

1. Hardware Requirements: Required when development involves specific hardware components or integration

2. Third-Party Software: Needed when third-party software or libraries will be incorporated

3. Service Levels: Include when ongoing service level commitments are required

4. Security Requirements: Required for projects with specific security compliance needs

5. International Transfer: Include when data or services cross international borders

6. Escrow Arrangements: Required when source code escrow is needed

7. Training and Documentation: Include when training or specific documentation deliverables are required

8. Disaster Recovery: Needed for critical systems or ongoing services

9. Personnel Requirements: Include when specific qualifications or security clearances are required

What schedules should be included in a Customer Development Agreement?

1. Schedule 1 - Services Specification: Detailed technical specifications and requirements

2. Schedule 2 - Project Plan: Timeline, milestones, and delivery dates

3. Schedule 3 - Charges and Payment: Detailed pricing, payment structure, and rates

4. Schedule 4 - Testing Procedures: Detailed testing methodology and acceptance criteria

5. Schedule 5 - Service Levels: Performance metrics and service level requirements

6. Schedule 6 - Personnel: Key personnel and their roles/responsibilities

7. Schedule 7 - Security Requirements: Detailed security protocols and requirements

8. Appendix A - Change Request Template: Standard form for requesting changes

9. Appendix B - Acceptance Certificate: Standard form for deliverable acceptance

Authors

Alex Denne

Advisor @ 蜜桃传媒AI | 3 x UCL-Certified in Contract Law & Drafting | 4+ Years Managing 1M+ Legal Documents

Jurisdiction

Ireland

Cost

Free to use

Find the document you need

Construction Development Agreement

An Irish law agreement governing construction development projects between developers and contractors, setting out key terms and regulatory compliance requirements.

Download

Business Development Contract

An Irish law-governed agreement establishing terms and conditions for business development services, including scope, compensation, and performance requirements.

Download

Web Developer Contract

An Irish law-governed contract establishing terms and conditions for web development services, including project scope, deliverables, and legal obligations.

Download

Web Developer Retainer Contract

An Irish-law governed contract establishing terms for ongoing web development services, including maintenance, development work, and service levels.

Download

Developer Contract Agreement

An Irish law-governed agreement for engaging software development services, defining key terms and obligations between parties.

Download

Builder Developer Agreement

An Irish law-governed agreement between a developer and builder establishing terms and conditions for construction project execution in Ireland.

Download

Property Development Partnership Agreement

An Irish law agreement establishing a partnership between parties for property development projects, defining roles, responsibilities, and profit-sharing arrangements.

Download

Building Development Agreement

An Irish law agreement governing the relationship between developer and landowner/employer for construction projects, setting out development terms, obligations, and requirements.

Download

Master Development Agreement

An Irish law agreement establishing the framework for large-scale development projects, including rights, obligations, and development requirements.

Download

Freelance Developer Contract

An Irish law-governed contract for engaging freelance software developers as independent contractors, covering services, payments, IP rights, and compliance requirements.

Download

Film Development Agreement

An Irish law-governed agreement establishing terms and conditions for film project development, including rights, responsibilities, and commercial arrangements.

Download

Development Rights Agreement

An Irish law agreement granting and regulating development rights for property, establishing terms between property owners and developers while ensuring compliance with Irish planning legislation.

Download

Performance And Development Agreement

An Irish law-governed agreement establishing performance metrics and development goals between employer and employee.

Download

Development Funding Agreement

An Irish law agreement governing the provision and terms of funding for development projects, including funding mechanisms, obligations, and security arrangements.

Download

Product Collaboration Agreement

An Irish law-governed agreement establishing terms for parties to collaborate on product development, manufacturing, or commercialization.

Download

Land Development Contract

An Irish law-governed agreement between landowner and developer establishing terms for land development, including planning, construction, and regulatory compliance requirements.

Download

Customer Development Agreement

An Irish law-governed agreement for custom software or technology development services between a service provider and customer, defining project terms and deliverables.

Download

Joint Software Development Agreement

An Irish law agreement governing collaborative software development between multiple parties, establishing rights, responsibilities, and project parameters.

Download

Forward Funding Agreement

An Irish law agreement governing the funding and purchase of a development project, establishing terms between funder and developer from site acquisition through to completion.

Download

Co Development Agreement

An Irish law-governed agreement establishing terms for collaborative development between parties, including IP rights, resource allocation, and project governance.

Download

Custom Software Development Agreement

An Irish law-governed agreement establishing terms and conditions for custom software development services, including project scope, deliverables, and compliance requirements.

Download

Agile Software Development Agreement

An Irish law-governed agreement for software development services using Agile methodology, defining terms, responsibilities, and deliverables for iterative development.

Download

Non Disclosure Agreement For Software Development

Irish law-governed NDA specifically designed for software development projects, protecting confidential information and intellectual property in technical environments.

Download

Project Development Agreement

An Irish law-governed agreement establishing the framework for property development projects, including rights, obligations, and development requirements.

Download

Product Development Agreement

An Irish law-governed agreement establishing terms for product development services, including development phases, deliverables, IP rights, and payment terms.

Download

Software Developer Contract

An Irish law-compliant employment contract for software developers, covering essential employment terms and technology-specific provisions.

Download

App Development Contract

An Irish law-governed contract establishing terms and conditions for mobile or web application development services, including project scope, deliverables, and IP rights.

Download

Website Development Agreement

An Irish law-governed agreement setting out terms and conditions for website development services, including scope, deliverables, and legal compliance requirements.

Download

Web Development Contract

An Irish law-governed agreement establishing terms and conditions for web development services, including project scope, deliverables, and compliance requirements.

Download

Joint Development Agreement

An Irish law-governed agreement establishing terms for collaborative development between multiple parties, covering IP rights, resources, and project governance.

Download
See more related templates

骋别苍颈别鈥檚 Security Promise

蜜桃传媒 is the safest place to draft. Here鈥檚 how we prioritise your privacy and security.

Your data is private:

We do not train on your data; 骋别苍颈别鈥檚 AI improves independently

All data stored on 蜜桃传媒 is private to your organisation

Your documents are protected:

Your documents are protected by ultra-secure 256-bit encryption

We are ISO27001 certified, so your data is secure

Organizational security:

You retain IP ownership of your documents and their information

You have full control over your data and who gets to see it

/** * 蜜桃传媒AI Template Page Script (Algolia + CMS fallback) * - Efficient Algolia search (lazy-loaded libs, no initial queries, 250ms debounce, min 2 chars). * - Shows CMS list by default; swaps to Algolia results only while searching. * - 4-column responsive grid, clickable title, purple (#673AB7) pill CTA. * - Counter shows "X of 37,541 shown". Pagination hidden if 鈮 one page (鈮 16 hits) or 0 hits. * - Empty state: "Generate your bespoke document" with compact dashed bubble + subcopy. * - Keeps existing accordion, exit-intent, Segment events, and create-document button logic. */ if (!window.__genieTemplateInit) { window.__genieTemplateInit = true; function runIdle(fn, timeout){ (window.requestIdleCallback || function(cb){ setTimeout(cb, 1); }) (fn, timeout ? {timeout} : undefined); } // ---------- Config ---------- const ALGOLIA_APP_ID = 'ZJLTMPL15I'; const ALGOLIA_SEARCH_KEY = 'b76a4b392b5c3d5eaf3ccdbe3008327a'; const ALGOLIA_INDEX_NAME = 'New Document List'; const DISPLAY_TOTAL_TEXT = '37,541'; const HITS_PER_PAGE = 16; const MIN_CHARS = 2; // do not fire queries for < 2 chars const INPUT_DEBOUNCE_MS = 250; // reduce API calls // ---------- Utilities ---------- function trackOnce(eventName, data = {}) { try { const key = `segmentEventFired-${eventName}`; if (sessionStorage.getItem(key)) return; if (typeof analytics !== "undefined" && typeof analytics.track === "function") { analytics.track(eventName, data); sessionStorage.setItem(key, "true"); } } catch (_) {} } const CLICK_DEBOUNCE_MS = 800; // prevent double window.open function safeOpenOnce(sourceEl, url, tgt = "_blank") { try { if (sourceEl && sourceEl.dataset.opening === "1") return; if (sourceEl) { sourceEl.dataset.opening = "1"; setTimeout(() => { try { delete sourceEl.dataset.opening; } catch(_){} }, CLICK_DEBOUNCE_MS); } } catch(_) {} window.open(url, tgt); } function loadScriptOnce(src) { return new Promise((resolve, reject) => { if (document.querySelector(`script[src="${src}"]`)) return resolve(); const s = document.createElement('script'); s.src = src; s.async = true; s.onload = resolve; s.onerror = reject; document.head.appendChild(s); }); } // Helper 鈥 Title Case with small words kept lowercase (except first/last) function toTitleCase(str) { const SMALL = new Set([ "a","an","and","as","at","but","by","for","from","in","into","nor", "of","on","onto","or","over","per","the","to","vs","via","with","upon" ]); function cap(w) { return w ? w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() : w; } function capCompound(w, isBoundary) { // Preserve delimiters, title-case segments; apply small-word rule to segments too return w.split(/([-_])/).map((seg, idx, arr) => { if (seg === "-" || seg === "_") return seg; const lower = seg.toLowerCase(); const firstSeg = idx === 0; const lastSeg = idx === arr.length - 1; if (!isBoundary && !firstSeg && !lastSeg && SMALL.has(lower)) return lower; // Preserve acronyms like NDA/LLC if (/^[A-Z0-9]{2,}$/.test(seg)) return seg; return cap(seg); }).join(""); } const words = (str || "").trim().split(/\s+/); return words.map((w, i) => { const lower = w.toLowerCase(); const isBoundary = (i === 0 || i === words.length - 1); // Preserve acronyms (e.g., NDA, USA) if (/^[A-Z0-9]{2,}$/.test(w)) return w; // Don鈥檛 capitalise 鈥渟mall words鈥 unless first/last if (!isBoundary && SMALL.has(lower)) return lower; // Handle hyphen/underscore compounds (e.g., non-compete, step-by-step) if (w.includes("-") || w.includes("_")) return capCompound(w, isBoundary); // Default case + apostrophes (e.g., it's -> It's) return cap(w); }).join(" "); } function showAlgoliaError(msg){ const el = document.createElement('div'); el.style.cssText='position:fixed;bottom:12px;left:12px;z-index:99999;background:#fff3f3;border:1px solid #ffc9c9;padding:8px 12px;border-radius:8px;color:#c00;font:14px/1.4 system-ui;box-shadow:0 2px 8px rgba(0,0,0,.08)'; el.textContent=msg; document.body.appendChild(el); setTimeout(()=>{ try{ el.remove(); }catch(_){} }, 8000); } // ---------- Main (load) ---------- window.addEventListener("load", function () { // --- Make the LCP H1 paint immediately on mobile (avoid fade-in delays) (function ensureImmediateH1Paint(){ if (!matchMedia('(max-width: 767px)').matches) return; var style = document.createElement('style'); style.textContent = ` /* If Webflow interactions set opacity/transform on header, override on mobile */ #heading-5 { opacity: 1 !important; transform: none !important; } `; document.head.appendChild(style); })(); injectAlgoliaStyles(); // --- Locale detection + strings (EN/PT/FR/IT/ES/DE) const htmlLang = (document.documentElement.lang || "").toLowerCase(); const pathLocale = (window.location.pathname.split("/")[1] || "").toLowerCase(); const langHint = (htmlLang || pathLocale || "").toLowerCase(); const isPT = langHint.includes("pt"); const isFR = langHint.includes("fr"); const isIT = langHint.includes("it"); const isES = langHint.includes("es"); const isDE = langHint.includes("de"); const currentLang = isPT ? "pt" : isFR ? "fr" : isIT ? "it" : isES ? "es" : isDE ? "de" : "en"; const I18N_MAP = { en: { searchPlaceholder: "Search templates鈥", noMatches: "No matches found.", generateBtn: "Generate your bespoke document", subcopy: "Let 蜜桃传媒's market-leading AI produce a new legally robust document in seconds.", getTemplate: "Get template", ariaSearch: "Search items", formatStats: (shown, total) => `${shown.toLocaleString()} of ${total} shown` }, pt: { searchPlaceholder: "Pesquisar modelos鈥", noMatches: "Nenhum resultado encontrado.", generateBtn: "Gerar o seu documento personalizado", subcopy: "Deixe a IA l铆der de mercado da 蜜桃传媒 criar, em segundos, um documento juridicamente s贸lido.", getTemplate: "Obter modelo", ariaSearch: "Pesquisar itens", formatStats: (shown, total) => `${shown.toLocaleString()} de ${total} mostrados` }, fr: { searchPlaceholder: "Rechercher des mod猫les鈥", noMatches: "Aucun r茅sultat.", generateBtn: "G茅n茅rez votre document sur mesure", subcopy: "L鈥橧A de pointe de 蜜桃传媒 cr茅e en quelques secondes un document juridiquement solide.", getTemplate: "Obtenir le mod猫le", ariaSearch: "Rechercher des 茅l茅ments", formatStats: (shown, total) => `${shown.toLocaleString()} sur ${total} affich茅s` }, it: { searchPlaceholder: "Cerca modelli鈥", noMatches: "Nessun risultato trovato.", generateBtn: "Genera il tuo documento su misura", subcopy: "L鈥橧A leader di 蜜桃传媒 crea in pochi secondi un documento giuridicamente solido.", getTemplate: "Ottieni il modello", ariaSearch: "Cerca elementi", formatStats: (shown, total) => `${shown.toLocaleString()} di ${total} visualizzati` }, es: { searchPlaceholder: "Buscar plantillas鈥", noMatches: "No se encontraron resultados.", generateBtn: "Genera tu documento a medida", subcopy: "La IA l铆der de 蜜桃传媒 crea en segundos un documento con solidez jur铆dica.", getTemplate: "Obtener plantilla", ariaSearch: "Buscar elementos", formatStats: (shown, total) => `${shown.toLocaleString()} de ${total} mostrados` }, de: { searchPlaceholder: "Vorlagen suchen鈥", noMatches: "Keine Ergebnisse gefunden.", generateBtn: "Individuelles Dokument erstellen", subcopy: "蜜桃传媒s f眉hrende KI erstellt in Sekunden ein rechtssicheres Dokument.", getTemplate: "Vorlage anzeigen", ariaSearch: "Elemente suchen", formatStats: (shown, total) => `${shown.toLocaleString()} von ${total} angezeigt` } }; const I18N = I18N_MAP[currentLang]; // --- Find CMS list and search input const cmsList = document.getElementById("post-list") || document.querySelector(".post_collection-wrapper"); let input = document.getElementById("post-search") || document.querySelector('#search-form_input\\ 2, .search-form_input-2'); // Create a minimal search input if none exists if (!input) { const bar = document.createElement("div"); bar.className = "search-bar"; bar.style.cssText = "display:flex;gap:.75rem;align-items:center;flex-wrap:wrap;justify-content:center;margin:0 0 .5rem 0;"; input = document.createElement("input"); input.id = "post-search"; input.type = "search"; input.placeholder = I18N.searchPlaceholder; input.setAttribute("aria-label", I18N.ariaSearch); input.style.cssText = "padding:.75rem 1rem;border:1px solid rgba(0,0,0,.12);border-radius:9999px;min-width:280px;max-width:720px;width:100%;"; bar.appendChild(input); (cmsList?.parentNode || document.body).insertBefore(bar, cmsList || null); } else { // Ensure placeholder respects locale if input already exists try { input.placeholder = I18N.searchPlaceholder; } catch(_) {} } // --- Stats line (centered) let statsEl = document.getElementById("search-count"); if (!statsEl) { statsEl = document.createElement("div"); statsEl.id = "search-count"; statsEl.style.cssText = "display:block;width:100%;text-align:center;margin-top:.5rem;"; input.parentNode.appendChild(statsEl); } // --- Governing law fallback const DEFAULT_GOV_LAW = 'United States'; function sanitizeGovLaw(v) { v = (v || '').trim(); return (!v || /^choose one\.{0,3}$/i.test(v)) ? DEFAULT_GOV_LAW : v; } // --- Prepare Algolia result containers just above CMS list const resultsParent = (cmsList && cmsList.parentNode) ? cmsList.parentNode : (statsEl.parentNode || document.body); let hitsEl = document.getElementById("algolia-hits"); if (!hitsEl) { hitsEl = document.createElement("div"); hitsEl.id = "algolia-hits"; hitsEl.style.cssText = "margin-top:1rem;width:100%;display:none;"; resultsParent.insertBefore(hitsEl, cmsList || null); } let paginationEl = document.getElementById("algolia-pagination"); if (!paginationEl) { paginationEl = document.createElement("div"); paginationEl.id = "algolia-pagination"; paginationEl.style.cssText = "margin:1rem 0;width:100%;display:none;"; resultsParent.insertBefore(paginationEl, cmsList || null); } // --- Toggle helpers const hasQuery = () => !!(input.value || "").trim(); function setCmsVisible(show) { if (!cmsList) return; cmsList.style.display = show ? "" : "none"; cmsList.setAttribute("aria-hidden", show ? "false" : "true"); } function setAlgoliaVisible(show) { hitsEl.style.display = show ? "" : "none"; paginationEl.style.display = show ? "" : "none"; } // Helper to ensure local empty UI never overlaps with Algolia view function hideLocalEmptyUI() { const createBtn = document.getElementById("no-results-create-btn"); const subcopy = document.getElementById("no-results-subcopy"); if (createBtn) createBtn.style.display = "none"; if (subcopy) subcopy.style.display = "none"; } // Initial: CMS visible; Algolia hidden; no counter setCmsVisible(true); setAlgoliaVisible(false); statsEl.textContent = ""; // --- Lazy Algolia bootstrap (only after user types 鈮 MIN_CHARS) let algoliaBootstrapped = false; let search = null; // --- Park InstantSearch CSS so it doesn't block first paint (function parkInstantSearchCSS(){ var link = Array.from(document.styleSheets || []) .map(function(s){return s.ownerNode;}) .find(function(n){ return n && n.tagName === 'LINK' && /instantsearch\.css/i.test(n.href); }); if (link && !link.dataset.parked) { link.media = 'print'; // non-matching media => not render-blocking link.dataset.parked = '1'; } // When/if we actually bootstrap Algolia, flip it back to 'all' window.__enableInstantSearchCSS = function(){ try { if (link) link.media = 'all'; } catch(_) {} }; })(); async function bootstrapAlgolia() { if (algoliaBootstrapped) return; algoliaBootstrapped = true; try { await loadScriptOnce("https://cdn.jsdelivr.net/npm/algoliasearch@4/dist/algoliasearch-lite.umd.js"); await loadScriptOnce("https://cdn.jsdelivr.net/npm/instantsearch.js@4/dist/instantsearch.production.min.js"); } catch (err) { console.error('Algolia libs failed to load', err); showAlgoliaError('Algolia libraries failed to load.'); return; } const searchClient = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_KEY); // Build "create" URL from current controls + query function currentGovLaw() { const el = document.getElementById("governing-law-alt") || document.getElementById("governing-law"); return sanitizeGovLaw((el?.value || "").trim()); } function currentKeyInfo() { const el = document.getElementById("key-requirements-alt") || document.getElementById("key-requirements"); return (el?.value || "").trim(); } const pageContractType = "Development Agreement".trim(); function buildCreateUrlFromQuery(q) { const appBaseURL = "https://app.genieai.co/create"; const url = `${appBaseURL}?contractType=${encodeURIComponent(pageContractType)}&governingLaw=${encodeURIComponent(currentGovLaw())}&keyInfo=${encodeURIComponent(currentKeyInfo())}&contractTitle=${encodeURIComponent(toTitleCase(q))}&showCFSModal=false`; return url; } // Debounce helper for input -> refine let inputTimer = null; function debouncedRefine(q) { if (!search) return; clearTimeout(inputTimer); inputTimer = setTimeout(() => { search.helper.setQuery(q).search(); }, INPUT_DEBOUNCE_MS); } // InstantSearch with a searchFunction to block empty/short queries search = instantsearch({ indexName: ALGOLIA_INDEX_NAME, searchClient, routing: false, searchFunction(helper) { const q = helper.state.query || ""; if (q.trim().length >= MIN_CHARS) { helper.search(); } else { // prevent network calls on start/short queries } } }); // Stats widget: update counter + pagination visibility const customStats = instantsearch.connectors.connectStats(({ nbHits }) => { const active = hasQuery(); statsEl.textContent = active ? I18N.formatStats(nbHits, DISPLAY_TOTAL_TEXT) : ''; if (paginationEl) { paginationEl.style.display = (active && nbHits > HITS_PER_PAGE) ? '' : 'none'; } }); search.addWidgets([ customStats({}), instantsearch.widgets.configure({ hitsPerPage: HITS_PER_PAGE, clickAnalytics: false }), instantsearch.widgets.hits({ container: hitsEl, templates: { item(hit) { const nameHtml = instantsearch.highlight({ attribute: 'Name', hit }); const bg = hit['Background'] || ''; const url = hit['CFS URL'] || '#'; return `

${nameHtml}

${bg}

${I18N.getTemplate}
`; }, empty: () => { const q = (input?.value || '').trim(); if (!q) return ''; const createhref = buildCreateUrlFromQuery(q); return `
${I18N.noMatches}
${I18N.generateBtn}
${I18N.subcopy}
`; } } }), instantsearch.widgets.pagination({ container: paginationEl, scrollTo: false }) ]); if (typeof window.__enableInstantSearchCSS === 'function') window.__enableInstantSearchCSS(); try { search.start(); } catch (err) { console.error('Algolia start failed', err); showAlgoliaError(err?.message || 'Algolia init failed. Check API key / referers / index.'); return; } // Hook input to debounced refine after bootstrap input.addEventListener('input', () => { const q = (input.value || '').trim(); if (q.length >= MIN_CHARS) { debouncedRefine(q); } }, { passive: true }); } // --- Lightweight local CMS filter (used only for < MIN_CHARS & as fallback) (function setupLocalCmsFilter() { if (!cmsList) return; let emptyEl = document.getElementById("no-results"); if (!emptyEl) { emptyEl = document.createElement("span"); emptyEl.id = "no-results"; emptyEl.style.display = "none"; input.parentNode?.appendChild(emptyEl); } let createBtn = document.getElementById("no-results-create-btn"); if (!createBtn) { createBtn = document.createElement("button"); createBtn.id = "no-results-create-btn"; createBtn.type = "button"; createBtn.textContent = I18N.generateBtn; createBtn.style.cssText = "display:none;margin:.5rem auto 0;padding:.6rem .9rem;border-radius:.5rem;border:1px solid rgba(0,0,0,.12);background:#fff;cursor:pointer;"; emptyEl.after(createBtn); } else { createBtn.textContent = I18N.generateBtn; createBtn.style.margin = ".5rem auto 0"; createBtn.style.display = "none"; } let subcopy = document.getElementById("no-results-subcopy"); if (!subcopy) { subcopy = document.createElement("div"); subcopy.id = "no-results-subcopy"; subcopy.textContent = I18N.subcopy; subcopy.style.cssText = "display:none;width:100%;text-align:center;margin-top:.5rem;font-family:'Roboto',system-ui,-apple-system,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif;font-size:.875rem;line-height:1.4;color:rgba(0,0,0,.65);"; createBtn.after(subcopy); } else { subcopy.textContent = I18N.subcopy; subcopy.style.display = "none"; subcopy.style.textAlign = "center"; } const items = Array.prototype.slice.call( cmsList.querySelectorAll(".post_collection-item, .w-dyn-item") ); if (!items.length) return; function norm(s) { return (s || "") .toLowerCase() .normalize("NFD").replace(/[\u0300-\u036f]/g, "") .replace(/[^a-z0-9\s]+/g, " ") .replace(/\s+/g, " ") .trim(); } function tokensOf(s) { return norm(s).split(" ").filter(Boolean); } function pickNameEl(item) { var el = item.querySelector("h1, h2, h3, h4, h5, h6") || item.querySelector('[class*="title" i]') || item.querySelector('[class*="name" i]'); if (el) return el; var nodes = Array.prototype.slice.call(item.querySelectorAll("*")); for (var i = 0; i < nodes.length; i++) { var n = nodes[i]; var tag = n.tagName && n.tagName.toLowerCase(); if (!tag || /^(svg|path|button|input|textarea|script|style|link|img)$/i.test(tag)) continue; var t = (n.textContent || "").trim(); if (!t) continue; var tl = t.toLowerCase(); if (tl.includes("find out more") || tl === "learn more" || tl === "read more") continue; if (t.length < 3 || t.length > 120) continue; return n; } return null; } items.forEach(function (item) { var nameEl = pickNameEl(item); var name = nameEl ? nameEl.textContent : ""; var tok = tokensOf(name); item.__nameTokens = tok; item.dataset.search = tok.join(" "); }); function setVisible(el, show) { el.style.display = show ? "" : "none"; el.setAttribute("aria-hidden", show ? "false" : "true"); } function applyFilter(q) { var qTokens = tokensOf(q); var visible = 0; if (!qTokens.length) { items.forEach((it) => setVisible(it, true)); if (emptyEl) emptyEl.style.display = "none"; createBtn.style.display = "none"; subcopy.style.display = "none"; return; } items.forEach(function (it) { var nameTokens = it.__nameTokens || []; var hit = qTokens.every(function (qt) { return nameTokens.some(function (nt) { return nt.indexOf(qt) !== -1; }); }); setVisible(it, hit); if (hit) visible++; }); const noResults = visible === 0; if (emptyEl) emptyEl.style.display = "none"; createBtn.style.display = (noResults && input.value.trim()) ? "block" : "none"; subcopy.style.display = (noResults && input.value.trim()) ? "block" : "none"; } // "Create" click (from local input) createBtn.addEventListener("click", function () { var searchTerm = (input.value || "").trim(); if (!searchTerm) return; var governingLaw = document.getElementById("governing-law-alt") || document.getElementById("governing-law"); var keyRequirements = document.getElementById("key-requirements-alt") || document.getElementById("key-requirements") || { value: "" }; var fallbackContractType = "Development Agreement".trim(); var cType = (typeof contractType !== "undefined" && contractType) ? contractType : fallbackContractType; var encodedTitle = encodeURIComponent(toTitleCase(searchTerm)); handleFormAction( null, governingLaw, keyRequirements, null, cType, encodedTitle, createBtn ); }); // Local filtering is only active while query length < MIN_CHARS input.addEventListener('input', () => { const q = (input.value || '').trim(); if (q.length < MIN_CHARS) applyFilter(q); }, { passive: true }); // Initial local state applyFilter(""); })(); // --- Input events: swap CMS/Algolia & (lazy) bootstrap + refine input.addEventListener("input", function () { const q = (input.value || "").trim(); const useAlgolia = q.length >= MIN_CHARS; setCmsVisible(!useAlgolia); setAlgoliaVisible(useAlgolia); if (useAlgolia) { hideLocalEmptyUI(); // prevent duplicate empty state when Algolia is active bootstrapAlgolia().then(() => { // refinement handled by debouncedRefine inside bootstrap }); } else { statsEl.textContent = ""; } }, { passive: true }); input.addEventListener("keydown", function (e) { if (e.key === "Escape") { input.value = ""; setCmsVisible(true); setAlgoliaVisible(false); hideLocalEmptyUI(); // also hide local empty UI on clear statsEl.textContent = ""; } }); // --- Governing Law Sync from Breadcrumb const breadcrumb = document.getElementById("breadcrumb-1"); const breadcrumbText = (breadcrumb?.textContent || "").trim(); const governingLawDropdowns = [ document.getElementById("governing-law"), document.getElementById("governing-law-alt") ].filter(Boolean); if (governingLawDropdowns.length && breadcrumbText) { governingLawDropdowns.forEach((ddl) => { let matchFound = false; Array.from(ddl.options).forEach((opt) => { if (opt.textContent.trim() === breadcrumbText) { opt.selected = true; matchFound = true; } }); if (!matchFound) ddl.selectedIndex = 0; }); } // --- Prevent governing-law dropdown/options from appearing in search snippets (function addNoSnippetToGovLaw() { // Helper: choose the most likely wrapper safely (works across variants) function markWrapper(selectEl) { if (!selectEl) return; // Prefer a dedicated wrapper if present var wrap = selectEl.closest('.doc-gen_select-wrapper') || selectEl.closest('.doc-gen_component-content-block') || selectEl.parentElement || selectEl; wrap.setAttribute('data-nosnippet', ''); } var govPrimary = document.getElementById('governing-law'); var govAlt = document.getElementById('governing-law-alt'); markWrapper(govPrimary); markWrapper(govAlt); })(); // --- Document Generator Setup (existing "create" buttons) function resolvePageNameFromSlug() { try { var path = (window.location && window.location.pathname) ? window.location.pathname : ""; var m = path.match(/\/template\/([^\/?#]+)/i); if (m && m[1]) return decodeURIComponent(m[1]).replace(/-/g, " "); var canonical = document.querySelector('link[rel="canonical"]')?.href || ""; var ogUrl = document.querySelector('meta[property="og:url"]')?.getAttribute("content") || ""; var urlToParse = canonical || ogUrl || ""; if (urlToParse) { try { var u = new URL(urlToParse); var m2 = u.pathname.match(/\/template\/([^\/?#]+)/i); if (m2 && m2[1]) return decodeURIComponent(m2[1]).replace(/-/g, " "); } catch(e){} } } catch(e){} var headingEl = document.getElementById("heading-5"); var hText = (headingEl?.textContent || "").trim(); if (hText) return hText; return (document.title || "").trim(); } const contractType = "Development Agreement".trim(); const rawContractTitle = resolvePageNameFromSlug(); const contractTitle = encodeURIComponent(toTitleCase(rawContractTitle)); const templateLinkEl = document.getElementById("template-link"); document.body.addEventListener("click", function (event) { let targetButton = event.target; while (targetButton && targetButton !== document.body) { if ( targetButton.id === "create-document" || targetButton.id === "create-document-alt" || targetButton.id === "create-document-alt-secondary" || targetButton.id === "create-document-image" || targetButton.id === "create-document-header" || targetButton.id === "create-document-header-primary" || targetButton.id === "create-document-header-secondary" ) { event.preventDefault(); event.stopImmediatePropagation(); let formId, governingLawId, keyRequirementsId; if (targetButton.id === "create-document") { formId = "document-generator"; governingLawId = "governing-law"; keyRequirementsId = "key-requirements"; } else { formId = "document-generator-alt"; governingLawId = "governing-law-alt"; keyRequirementsId = "key-requirements-alt"; } const form = document.getElementById(formId); const governingLaw = document.getElementById(governingLawId); const keyRequirements = document.getElementById(keyRequirementsId); if (form && governingLaw && keyRequirements) { handleFormAction( form, governingLaw, keyRequirements, templateLinkEl, contractType, contractTitle, targetButton ); } return; } targetButton = targetButton.parentElement; } }, false); function setupDocumentGeneratorForm(formId, governingLawId, keyRequirementsId) { const form = document.getElementById(formId); const governingLaw = document.getElementById(governingLawId); const keyRequirements = document.getElementById(keyRequirementsId); if (!form || !governingLaw || !keyRequirements) return; const observer = new IntersectionObserver( (entries, obs) => { if (entries[0]?.isIntersecting) obs.disconnect(); }, { threshold: 0.1 } ); observer.observe(form); form.setAttribute("data-wf-ignore", "true"); form.addEventListener("keydown", function (event) { if (event.key === "Enter") event.preventDefault(); }); } function handleFormAction( form, governingLaw, keyRequirements, templateLinkEl, contractType, contractTitle, sourceEl ) { const governingLawValue = governingLaw?.value?.trim?.() || ""; const gov = sanitizeGovLaw(governingLawValue); const keyInfoValue = keyRequirements?.value?.trim?.() || ""; if (!gov) return; setTimeout(() => { trackOnce("visitor website-generator hero-create submit-clicked", { keyRequirements: keyInfoValue, governingLaw: gov, contractType, contractTitle: decodeURIComponent(contractTitle), pageType: "Generator" }); }, 300); const appBaseURL = "https://app.genieai.co/create"; const templateLinkURL = templateLinkEl?.getAttribute?.("data-template-link"); if (templateLinkURL && templateLinkURL.trim() && !keyInfoValue && form) { safeOpenOnce(sourceEl, templateLinkURL.trim(), "_blank"); return; } const redirectURL = `${appBaseURL}?contractType=${encodeURIComponent( contractType )}&governingLaw=${encodeURIComponent( gov )}&keyInfo=${encodeURIComponent( keyInfoValue )}&contractTitle=${contractTitle}&showCFSModal=false`; safeOpenOnce(sourceEl, redirectURL, "_blank"); } setupDocumentGeneratorForm("document-generator", "governing-law", "key-requirements"); setupDocumentGeneratorForm("document-generator-alt", "governing-law-alt", "key-requirements-alt"); // --- Review Document Click Tracking const reviewDocumentEl = document.getElementById("review-document"); if (reviewDocumentEl) { reviewDocumentEl.addEventListener("click", function () { trackOnce("visitor website-generator hero-review upload-clicked"); }); } }); // --- CWV Improvement: Defer Webflow ix2 window.Webflow ||= []; window.Webflow.push(function () { (window.requestIdleCallback || function (cb) { setTimeout(cb, 1); })(() => { try { const ix2 = Webflow.require?.("ix2"); if (ix2?.init) ix2.init(); } catch (e) { console.warn("Webflow ix2 defer failed:", e); } }); }); // ---------- Styles ---------- function injectAlgoliaStyles() { if (document.getElementById("algolia-hit-styles")) return; const css = ` #algolia-hits { width: 100%; } /* Responsive 4-col grid on desktop */ #algolia-hits .ais-Hits-list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; list-style: none; padding: 0; margin: 0; } /* Remove Algolia theme wrapper spacing */ #algolia-hits .ais-Hits-item { width: 100% !important; margin: 0 !important; border: 0 !important; padding: 0 !important; background: transparent !important; box-shadow: none !important; } @media (max-width: 991px) { #algolia-hits .ais-Hits-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 599px) { #algolia-hits .ais-Hits-list { grid-template-columns: 1fr; } } /* Card */ .alg-card { border: 1px solid rgba(0,0,0,.08); border-radius: 12px; padding: 16px; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.04); display: flex; flex-direction: column; height: 100%; } .alg-card h3 { margin: 0 0 8px 0; font-size: 1rem; line-height: 1.3; } .alg-card p { margin: .25rem 0 .9rem 0; color: rgba(0,0,0,.75); font-size: .95rem; line-height: 1.45; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; /* clamp to 4 lines */ overflow: hidden; } .alg-hit-title { color: inherit; text-decoration: none; } .alg-hit-title:hover { text-decoration: underline; } /* Purple pill button (#673AB7), left-aligned, not full-width */ .alg-btn-primary { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: .6rem 1.25rem; border-radius: 9999px; background: #673AB7; color: #fff !important; text-decoration: none; font-weight: 600; border: none; box-shadow: 0 1px 2px rgba(0,0,0,.06); transition: filter .15s ease, transform .02s ease; margin-top: auto; /* stick to bottom of card */ } .alg-btn-primary:hover { filter: brightness(0.95); } .alg-btn-primary:active { transform: translateY(1px); } .alg-btn-primary:focus { outline: 2px solid rgba(103,58,183,.35); outline-offset: 2px; } `; const style = document.createElement('style'); style.id = "algolia-hit-styles"; style.textContent = css; document.head.appendChild(style); } }