// Contact-page tweaks — three expressive, feel-reshaping controls. const { useEffect } = React; function ContactTweaks() { const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "layout": "split", "channels": "table", "motif": "rings" }/*EDITMODE-END*/; const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); useEffect(() => { const grid = document.querySelector('.contact-grid'); const channels = document.querySelector('.contact-channels'); const form = document.querySelector('.contact-form'); const hero = document.querySelector('.content-hero'); if (!grid || !channels || !form || !hero) return; // —— LAYOUT — reshapes how the page presents form vs channels —— grid.style.display = ''; grid.style.gridTemplateColumns = ''; grid.style.gap = ''; grid.style.maxWidth = ''; grid.style.margin = ''; form.style.padding = ''; form.style.background = ''; form.style.border = ''; form.style.boxShadow = ''; form.style.borderRadius = ''; if (t.layout === 'split') { // default — two columns side by side grid.style.gridTemplateColumns = '1fr 1fr'; grid.style.gap = '80px'; } else if (t.layout === 'centered') { // single intimate column, channels at top, form below, max 720px grid.style.gridTemplateColumns = '1fr'; grid.style.maxWidth = '720px'; grid.style.margin = '0 auto'; grid.style.gap = '60px'; form.style.padding = '48px'; form.style.boxShadow = '0 40px 80px -20px rgba(0,0,0,0.4)'; } else if (t.layout === 'overlay') { // form floats over a wider channel canvas — overlapping cards grid.style.gridTemplateColumns = '1fr'; grid.style.gap = '0'; grid.style.position = 'relative'; form.style.position = 'relative'; form.style.marginTop = '-80px'; form.style.marginLeft = 'auto'; form.style.maxWidth = '560px'; form.style.padding = '48px'; form.style.boxShadow = '0 40px 100px -20px rgba(0,0,0,0.5), 0 0 0 1px rgba(31,184,122,0.15)'; form.style.background = 'var(--ink)'; form.style.zIndex = '2'; } // —— CHANNELS — reshapes how contact methods are listed —— if (t.channels === 'table') { // default — quiet table-like rows channels.style.display = 'flex'; channels.style.flexDirection = 'column'; channels.style.gap = '4px'; channels.querySelectorAll('.contact-channel').forEach(el => { el.style.display = 'grid'; el.style.gridTemplateColumns = '100px 1fr auto'; el.style.gap = '24px'; el.style.padding = '24px 0'; el.style.background = ''; el.style.border = ''; el.style.borderBottom = '1px solid var(--hairline)'; el.style.borderRadius = ''; el.style.alignItems = 'center'; }); } else if (t.channels === 'cards') { // confident card stack with hover lift channels.style.display = 'grid'; channels.style.gridTemplateColumns = '1fr 1fr'; channels.style.gap = '12px'; channels.querySelectorAll('.contact-channel').forEach(el => { el.style.display = 'flex'; el.style.flexDirection = 'column'; el.style.gridTemplateColumns = ''; el.style.gap = '12px'; el.style.padding = '24px'; el.style.background = 'var(--midnight)'; el.style.border = '1px solid var(--hairline)'; el.style.borderRadius = '4px'; el.style.alignItems = 'flex-start'; }); } else if (t.channels === 'editorial') { // big, generous, editorial — each channel a hero of its own channels.style.display = 'flex'; channels.style.flexDirection = 'column'; channels.style.gap = '0'; channels.querySelectorAll('.contact-channel').forEach((el, i) => { el.style.display = 'grid'; el.style.gridTemplateColumns = '60px 1fr'; el.style.gap = '32px'; el.style.padding = '36px 0'; el.style.borderBottom = '1px solid var(--hairline)'; el.style.background = ''; el.style.border = ''; el.style.alignItems = 'baseline'; const info = el.querySelector('.contact-channel-info'); if (info) { info.style.fontSize = '32px'; info.style.lineHeight = '1.15'; } // hide the small response-time badge in editorial mode const last = el.children[el.children.length - 1]; if (last && last !== info && last.classList.contains('mono')) last.style.display = 'none'; }); } // —— MOTIF — ambient hero treatment —— let motifBg = hero.querySelector('.contact-motif'); if (!motifBg) { motifBg = document.createElement('div'); motifBg.className = 'contact-motif'; motifBg.style.cssText = 'position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;opacity:0.6;'; hero.style.position = 'relative'; hero.style.overflow = 'hidden'; hero.insertBefore(motifBg, hero.firstChild); // make sure inner content is on top const inner = hero.querySelector('.container-wide'); if (inner) { inner.style.position = 'relative'; inner.style.zIndex = '1'; } } if (t.motif === 'rings') { motifBg.innerHTML = ` `; } else if (t.motif === 'grid') { motifBg.innerHTML = ` N° 010 · CONTACT `; } else if (t.motif === 'wave') { motifBg.innerHTML = ` `; } else if (t.motif === 'none') { motifBg.innerHTML = ''; } }, [t]); return ( setTweak('layout', v)} options={[ { value: 'split', label: 'Split' }, { value: 'centered', label: 'Centered' }, { value: 'overlay', label: 'Overlay' } ]} /> setTweak('channels', v)} options={[ { value: 'table', label: 'Quiet table' }, { value: 'cards', label: 'Card grid' }, { value: 'editorial', label: 'Editorial' } ]} /> setTweak('motif', v)} options={[ { value: 'rings', label: 'Rings' }, { value: 'grid', label: 'Survey grid' }, { value: 'wave', label: 'Waveform' }, { value: 'none', label: 'None' } ]} /> ); } const ctTweakRoot = document.createElement('div'); ctTweakRoot.id = 'contact-tweaks-root'; document.body.appendChild(ctTweakRoot); ReactDOM.createRoot(ctTweakRoot).render();