/* VEIA search — client-side, no dependency, minimal design */ (function(){ 'use strict'; var INDEX_URL = '/search-index.json'; var STATE = { idx: null, loading: null }; // === Icon injection in main-nav === function injectIcon(){ var mainNav = document.querySelector('nav.main-nav'); if (!mainNav) return; var svgHtml = ''; // 1) Bouton desktop : dans .nav-links (visible >880px) var navLinks = mainNav.querySelector('.nav-links'); if (navLinks && !navLinks.querySelector('.veia-search-trigger')){ var btnD = document.createElement('button'); btnD.type = 'button'; btnD.className = 'veia-search-trigger'; btnD.setAttribute('aria-label', 'Rechercher sur le site'); btnD.title = 'Rechercher (⌘K)'; btnD.innerHTML = svgHtml; navLinks.appendChild(btnD); btnD.addEventListener('click', openOverlay); } // 2) Bouton mobile : dans nav.main-nav avant .nav-burger (visible ≤880px) if (!mainNav.querySelector('.veia-search-trigger-mobile')){ var btnM = document.createElement('button'); btnM.type = 'button'; btnM.className = 'veia-search-trigger veia-search-trigger-mobile'; btnM.setAttribute('aria-label', 'Rechercher sur le site'); btnM.title = 'Rechercher'; btnM.innerHTML = svgHtml; var burger = mainNav.querySelector('.nav-burger'); if (burger) mainNav.insertBefore(btnM, burger); else mainNav.appendChild(btnM); btnM.addEventListener('click', openOverlay); } } // === CSS injection === function injectCss(){ if (document.getElementById('veia-search-css')) return; var css = '' + '.veia-search-trigger{background:transparent;border:none;padding:6px 8px;margin-left:8px;color:inherit;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:color .18s ease,opacity .18s ease;opacity:.78;}.veia-search-trigger-mobile{display:none;margin-left:0;margin-right:14px;width:44px;height:44px;padding:0;}@media (max-width:880px){.nav-links .veia-search-trigger{display:none;}.veia-search-trigger-mobile{display:inline-flex;}}' + '.veia-search-trigger:hover,.veia-search-trigger:focus-visible{color:inherit;opacity:1;outline:none;}' + '.veia-search-overlay{position:fixed;inset:0;background:rgba(26,35,50,.72);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);z-index:9999;opacity:0;pointer-events:none;transition:opacity .22s ease;display:flex;align-items:flex-start;justify-content:center;padding:88px 20px 20px;overflow-y:auto;}' + '.veia-search-overlay.open{opacity:1;pointer-events:auto;}' + '.veia-search-panel{background:#fff;width:100%;max-width:720px;box-shadow:0 24px 68px rgba(0,0,0,.24);transform:translateY(-8px);transition:transform .22s ease;display:flex;flex-direction:column;max-height:calc(100vh - 108px);}' + '.veia-search-overlay.open .veia-search-panel{transform:translateY(0);}' + '.veia-search-inputwrap{display:flex;align-items:center;gap:14px;padding:22px 24px;border-bottom:1px solid rgba(29,77,126,.14);}' + '.veia-search-inputwrap svg{flex-shrink:0;color:var(--ardoise,#566372);}' + '.veia-search-input{flex:1;border:none;outline:none;background:transparent;font-family:"Fraunces",Georgia,serif;font-size:22px;font-weight:400;color:var(--encre,#1a2332);letter-spacing:-0.01em;}' + '.veia-search-input::placeholder{color:rgba(29,77,126,.4);font-style:italic;}' + '.veia-search-close{background:transparent;border:1px solid rgba(29,77,126,.18);color:var(--ardoise,#566372);cursor:pointer;font-family:"Inter",sans-serif;font-size:11px;letter-spacing:.08em;padding:6px 10px;text-transform:uppercase;transition:all .18s ease;flex-shrink:0;}' + '.veia-search-close:hover{background:var(--encre,#1a2332);color:#fff;border-color:var(--encre,#1a2332);}' + '.veia-search-results{overflow-y:auto;padding:4px 0 16px;}' + '.veia-search-empty{padding:36px 24px;text-align:center;font-family:"Inter",sans-serif;font-size:14px;color:var(--ardoise,#566372);}' + '.veia-search-empty em{font-family:"Fraunces",serif;font-style:italic;color:var(--encre,#1a2332);display:block;font-size:16px;margin-bottom:6px;}' + '.veia-search-group{padding:14px 0 4px;}' + '.veia-search-group-label{font-family:"Inter",sans-serif;font-size:10.5px;font-weight:600;letter-spacing:.18em;text-transform:uppercase;color:var(--accent,#1d4d7e);padding:0 24px 8px;}' + '.veia-search-item{display:block;padding:14px 24px;text-decoration:none;color:inherit;border-left:2px solid transparent;transition:background .16s ease,border-color .16s ease;}' + '.veia-search-item:hover,.veia-search-item.active{background:var(--ivoire,#f8f7f4);border-left-color:var(--accent,#1d4d7e);}' + '.veia-search-item-title{font-family:"Fraunces",serif;font-size:16px;font-weight:400;color:var(--encre,#1a2332);line-height:1.35;margin:0 0 4px;}' + '.veia-search-item-desc{font-family:"Inter",sans-serif;font-size:13px;line-height:1.5;color:var(--ardoise,#566372);margin:0;}' + '.veia-search-item mark{background:rgba(29,77,126,.14);color:var(--accent,#1d4d7e);padding:0 1px;border-radius:2px;font-weight:500;}' + '.veia-search-hint{padding:10px 24px 4px;font-family:"Inter",sans-serif;font-size:11px;color:var(--ardoise,#566372);display:flex;gap:16px;flex-wrap:wrap;border-top:1px solid rgba(29,77,126,.08);}' + '.veia-search-hint kbd{background:var(--ivoire,#f8f7f4);border:1px solid rgba(29,77,126,.14);padding:2px 6px;font-family:"Inter",sans-serif;font-size:11px;color:var(--encre,#1a2332);}' + '@media (max-width:640px){.veia-search-input{font-size:18px;}.veia-search-item-title{font-size:15px;}.veia-search-item-desc{font-size:12.5px;}.veia-search-inputwrap{padding:18px;}.veia-search-item{padding:12px 18px;}.veia-search-group-label{padding:0 18px 6px;}}'; var el = document.createElement('style'); el.id = 'veia-search-css'; el.textContent = css; document.head.appendChild(el); } // === Overlay markup === function ensureOverlay(){ if (document.getElementById('veia-search-overlay')) return document.getElementById('veia-search-overlay'); var wrap = document.createElement('div'); wrap.id = 'veia-search-overlay'; wrap.className = 'veia-search-overlay'; wrap.setAttribute('role','dialog'); wrap.setAttribute('aria-modal','true'); wrap.setAttribute('aria-label','Recherche sur veia.ai'); wrap.innerHTML = '' + '
' + '
' + ' ' + ' ' + ' ' + '
' + '
' + '
naviguerEntrée ouvrirEsc fermer
' + '
'; document.body.appendChild(wrap); wrap.addEventListener('click', function(e){ if (e.target === wrap) closeOverlay(); }); wrap.querySelector('.veia-search-close').addEventListener('click', closeOverlay); var input = wrap.querySelector('.veia-search-input'); input.addEventListener('input', function(){ render(input.value); }); input.addEventListener('keydown', onKey); return wrap; } function openOverlay(){ injectCss(); var wrap = ensureOverlay(); loadIndex(); wrap.classList.add('open'); document.body.style.overflow = 'hidden'; setTimeout(function(){ wrap.querySelector('.veia-search-input').focus(); render(''); }, 30); } function closeOverlay(){ var wrap = document.getElementById('veia-search-overlay'); if (!wrap) return; wrap.classList.remove('open'); document.body.style.overflow = ''; } function loadIndex(){ if (STATE.idx || STATE.loading) return STATE.loading; STATE.loading = fetch(INDEX_URL, { cache: 'default' }) .then(function(r){ return r.json(); }) .then(function(j){ STATE.idx = j; return j; }) .catch(function(){ STATE.idx = []; return []; }); return STATE.loading; } // Naive scorer: substring match on title/desc/kicker, weighted function normalize(s){ return (s||'').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g,''); } function score(item, q){ var t = normalize(item.t), d = normalize(item.d), k = normalize(item.k), c = normalize(item.c); if (!q) return 0; var sc = 0; if (t.indexOf(q) === 0) sc += 100; else if (t.indexOf(q) !== -1) sc += 60; if (k.indexOf(q) !== -1) sc += 30; if (d.indexOf(q) !== -1) sc += 20; if (c.indexOf(q) !== -1) sc += 10; // multi-word: all tokens must appear somewhere var toks = q.split(/\s+/).filter(Boolean); if (toks.length > 1){ var full = t + ' ' + d + ' ' + k + ' ' + c; var allIn = toks.every(function(tok){ return full.indexOf(tok) !== -1; }); if (allIn) sc += 40; else sc = Math.max(0, sc - 20); } return sc; } function highlight(text, q){ if (!q) return escHtml(text); var re = new RegExp('(' + q.split(/\s+/).filter(Boolean).map(escRe).join('|') + ')', 'gi'); return escHtml(text).replace(re, '$1'); } function escHtml(s){ return String(s||'').replace(/[&<>"']/g, function(c){ return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; }); } function escRe(s){ return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'); } var CATEGORY_ORDER = ['Blog','Doctrine','Services','Secteurs','Rôles','Publications','Accueil']; function render(q){ loadIndex().then(function(){ var wrap = document.getElementById('veia-search-overlay'); if (!wrap) return; var results = wrap.querySelector('.veia-search-results'); var qn = normalize((q||'').trim()); var items; if (!qn){ // Empty state: show a curated shortlist var featured = ['/','/blog/','/services.html','/doctrine.html','/methode.html','/charte-ia-entreprise.html','/diagnostic-gouvernance-ia.html','/iapourmonentreprise']; items = STATE.idx.filter(function(x){ return featured.indexOf(x.u) !== -1; }); } else { items = STATE.idx.map(function(x){ return {x:x, s:score(x, qn)}; }) .filter(function(r){ return r.s > 0; }) .sort(function(a,b){ return b.s - a.s; }) .slice(0, 40) .map(function(r){ return r.x; }); } if (items.length === 0){ results.innerHTML = '
Aucun résultat.Essayez avec un autre mot ou parcourez toutes les expertises.
'; return; } // Group by category var groups = {}; items.forEach(function(it){ (groups[it.c] = groups[it.c] || []).push(it); }); var html = ''; var groupLabel = qn ? '' : '
Suggestions
'; html += groupLabel; CATEGORY_ORDER.forEach(function(cat){ var arr = groups[cat]; if (!arr || !arr.length) return; if (qn){ html += '
' + escHtml(cat) + '
'; } arr.forEach(function(it){ html += '' + '
' + highlight(it.t, qn) + '
' + (it.d ? '
' + highlight(it.d.length > 160 ? it.d.slice(0,157)+'…' : it.d, qn) + '
' : '') + '
'; }); if (qn){ html += '
'; } }); results.innerHTML = html; setActive(0); }); } function setActive(i){ var wrap = document.getElementById('veia-search-overlay'); if (!wrap) return; var items = wrap.querySelectorAll('.veia-search-item'); if (!items.length) return; if (i < 0) i = items.length - 1; if (i >= items.length) i = 0; items.forEach(function(el){ el.classList.remove('active'); }); items[i].classList.add('active'); items[i].scrollIntoView({block:'nearest'}); wrap.dataset.active = String(i); } function onKey(e){ var wrap = document.getElementById('veia-search-overlay'); if (!wrap) return; var items = wrap.querySelectorAll('.veia-search-item'); var cur = parseInt(wrap.dataset.active||'0', 10); if (e.key === 'ArrowDown'){ e.preventDefault(); setActive(cur+1); } else if (e.key === 'ArrowUp'){ e.preventDefault(); setActive(cur-1); } else if (e.key === 'Enter'){ e.preventDefault(); if (items[cur]) window.location.href = items[cur].getAttribute('href'); } } // Global shortcuts document.addEventListener('keydown', function(e){ if ((e.key === 'k' || e.key === 'K') && (e.metaKey || e.ctrlKey)){ e.preventDefault(); openOverlay(); } else if (e.key === 'Escape'){ closeOverlay(); } else if (e.key === '/' && !/(INPUT|TEXTAREA|SELECT)/.test((e.target && e.target.tagName) || '')){ e.preventDefault(); openOverlay(); } }); function init(){ injectCss(); injectIcon(); } if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init); else init(); })();