616 lines
22 KiB
JavaScript
616 lines
22 KiB
JavaScript
/**
|
|
* REBOURS — Main Script
|
|
* CAD/CAO-inspired interface · GSAP ScrollTrigger · Technical drawing overlays · Ambient sound
|
|
*/
|
|
|
|
import gsap from 'gsap';
|
|
import { ScrollTrigger } from 'gsap/ScrollTrigger';
|
|
|
|
gsap.registerPlugin(ScrollTrigger);
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
// ---- CONFIG ----
|
|
const isMobile = window.innerWidth <= 600;
|
|
const isTouch = 'ontouchstart' in window;
|
|
|
|
// ---- HEADER HEIGHT → CSS VAR ----
|
|
const setHeaderHeight = () => {
|
|
const h = document.querySelector('.header')?.offsetHeight || 44;
|
|
document.documentElement.style.setProperty('--header-h', h + 'px');
|
|
};
|
|
setHeaderHeight();
|
|
window.addEventListener('resize', setHeaderHeight);
|
|
|
|
// ==========================================================
|
|
// 1. CAD CROSSHAIR CURSOR WITH X/Y COORDINATES
|
|
// ==========================================================
|
|
|
|
let attachCursorHover = () => {};
|
|
|
|
if (!isMobile && !isTouch) {
|
|
const cursorH = document.createElement('div');
|
|
cursorH.className = 'cad-h';
|
|
const cursorV = document.createElement('div');
|
|
cursorV.className = 'cad-v';
|
|
const cursorCenter = document.createElement('div');
|
|
cursorCenter.className = 'cad-center';
|
|
const cursorCoords = document.createElement('div');
|
|
cursorCoords.className = 'cad-coords';
|
|
|
|
[cursorH, cursorV, cursorCenter, cursorCoords].forEach(el => document.body.appendChild(el));
|
|
|
|
let visible = false;
|
|
|
|
window.addEventListener('mousemove', (e) => {
|
|
const x = e.clientX;
|
|
const y = e.clientY;
|
|
|
|
cursorH.style.left = (x - 16) + 'px';
|
|
cursorH.style.top = y + 'px';
|
|
cursorV.style.left = x + 'px';
|
|
cursorV.style.top = (y - 16) + 'px';
|
|
cursorCenter.style.left = x + 'px';
|
|
cursorCenter.style.top = y + 'px';
|
|
cursorCoords.style.left = (x + 16) + 'px';
|
|
cursorCoords.style.top = (y + 14) + 'px';
|
|
|
|
cursorCoords.textContent =
|
|
'X:' + String(Math.round(x)).padStart(4, '0') +
|
|
' Y:' + String(Math.round(y)).padStart(4, '0');
|
|
|
|
if (!visible) {
|
|
visible = true;
|
|
[cursorH, cursorV, cursorCenter, cursorCoords].forEach(el => {
|
|
el.style.opacity = '1';
|
|
});
|
|
}
|
|
});
|
|
|
|
attachCursorHover = (elements) => {
|
|
elements.forEach(el => {
|
|
el.addEventListener('mouseenter', () => {
|
|
cursorH.classList.add('cad-hover');
|
|
cursorV.classList.add('cad-hover');
|
|
cursorCenter.classList.add('cad-hover');
|
|
});
|
|
el.addEventListener('mouseleave', () => {
|
|
cursorH.classList.remove('cad-hover');
|
|
cursorV.classList.remove('cad-hover');
|
|
cursorCenter.classList.remove('cad-hover');
|
|
});
|
|
});
|
|
};
|
|
|
|
attachCursorHover(document.querySelectorAll(
|
|
'a, button, input, .product-card, summary, .panel-close'
|
|
));
|
|
|
|
// WhatsApp hover — green center dot
|
|
document.querySelectorAll('.whatsapp-btn').forEach(el => {
|
|
el.addEventListener('mouseenter', () => cursorCenter.classList.add('cad-whatsapp'));
|
|
el.addEventListener('mouseleave', () => cursorCenter.classList.remove('cad-whatsapp'));
|
|
});
|
|
}
|
|
|
|
// ==========================================================
|
|
// 2. INTERACTIVE GRID
|
|
// ==========================================================
|
|
|
|
const gridContainer = document.getElementById('interactive-grid');
|
|
const COLORS = [
|
|
'rgba(232,168,0,0.45)',
|
|
'rgba(232,168,0,0.32)',
|
|
'rgba(232,168,0,0.18)',
|
|
];
|
|
|
|
function buildGrid() {
|
|
if (!gridContainer) return;
|
|
gridContainer.innerHTML = '';
|
|
const CELL = isMobile ? 38 : 60;
|
|
const cols = Math.ceil(window.innerWidth / CELL);
|
|
const rows = Math.ceil(window.innerHeight / CELL);
|
|
gridContainer.style.display = 'grid';
|
|
gridContainer.style.gridTemplateColumns = `repeat(${cols}, ${CELL}px)`;
|
|
gridContainer.style.gridTemplateRows = `repeat(${rows}, ${CELL}px)`;
|
|
|
|
for (let i = 0; i < cols * rows; i++) {
|
|
const cell = document.createElement('div');
|
|
cell.className = 'grid-cell';
|
|
cell.addEventListener('mouseenter', () => {
|
|
cell.style.transition = 'none';
|
|
cell.style.backgroundColor = COLORS[Math.floor(Math.random() * COLORS.length)];
|
|
});
|
|
cell.addEventListener('mouseleave', () => {
|
|
cell.style.transition = 'background-color 1.4s ease-out';
|
|
cell.style.backgroundColor = 'transparent';
|
|
});
|
|
gridContainer.appendChild(cell);
|
|
}
|
|
}
|
|
|
|
buildGrid();
|
|
let rt;
|
|
window.addEventListener('resize', () => { clearTimeout(rt); rt = setTimeout(buildGrid, 150); });
|
|
|
|
// ==========================================================
|
|
// 3. GSAP SCROLL ANIMATIONS — CAD REVEAL
|
|
// ==========================================================
|
|
|
|
// ---- Header fade in ----
|
|
const header = document.querySelector('.header');
|
|
if (header) {
|
|
gsap.fromTo(header,
|
|
{ opacity: 0, y: -10 },
|
|
{ opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' }
|
|
);
|
|
}
|
|
|
|
// ---- Hero animations (scroll-triggered, replay in/out) ----
|
|
const heroLabel = document.querySelector('.hero-left .label');
|
|
const heroH1 = document.querySelector('.hero-left h1');
|
|
const heroSubs = document.querySelectorAll('.hero-sub');
|
|
const heroImg = document.querySelector('.hero-img');
|
|
const heroRight = document.querySelector('.hero-right');
|
|
|
|
const heroTl = gsap.timeline({
|
|
defaults: { ease: 'power3.out' },
|
|
scrollTrigger: {
|
|
trigger: '.hero',
|
|
start: 'top 95%',
|
|
end: 'bottom 5%',
|
|
toggleActions: 'play reverse play reverse',
|
|
},
|
|
});
|
|
|
|
if (heroLabel) {
|
|
heroTl.fromTo(heroLabel,
|
|
{ opacity: 0, x: -20 },
|
|
{ opacity: 1, x: 0, duration: 0.6 },
|
|
0.1
|
|
);
|
|
}
|
|
|
|
if (heroH1) {
|
|
heroTl.fromTo(heroH1,
|
|
{ opacity: 0, y: 40, clipPath: 'inset(0 0 100% 0)' },
|
|
{ opacity: 1, y: 0, clipPath: 'inset(0 0 0% 0)', duration: 1 },
|
|
0.2
|
|
);
|
|
}
|
|
|
|
heroSubs.forEach((sub, i) => {
|
|
heroTl.fromTo(sub,
|
|
{ opacity: 0, y: 20 },
|
|
{ opacity: 1, y: 0, duration: 0.6 },
|
|
0.5 + i * 0.15
|
|
);
|
|
});
|
|
|
|
if (heroImg && heroRight) {
|
|
heroTl.fromTo(heroRight,
|
|
{ clipPath: 'inset(0 0 0 100%)' },
|
|
{ clipPath: 'inset(0 0 0 0%)', duration: 1.2, ease: 'power4.inOut' },
|
|
0.3
|
|
);
|
|
heroTl.fromTo(heroImg,
|
|
{ scale: 1.15, opacity: 0 },
|
|
{ scale: 1, opacity: 0.92, duration: 1.4, ease: 'power2.out' },
|
|
0.4
|
|
);
|
|
}
|
|
|
|
// Hero parallax on scroll
|
|
if (heroImg) {
|
|
gsap.to(heroImg, {
|
|
yPercent: 15,
|
|
ease: 'none',
|
|
scrollTrigger: {
|
|
trigger: '.hero',
|
|
start: 'top top',
|
|
end: 'bottom top',
|
|
scrub: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
// ---- Collection header: construction line draw-in ----
|
|
const collectionHeader = document.querySelector('.collection-header');
|
|
if (collectionHeader) {
|
|
const line = document.createElement('div');
|
|
line.className = 'cad-construction-line';
|
|
collectionHeader.appendChild(line);
|
|
|
|
gsap.fromTo(line,
|
|
{ scaleX: 0 },
|
|
{
|
|
scaleX: 1,
|
|
transformOrigin: 'left center',
|
|
duration: 0.8,
|
|
ease: 'power2.out',
|
|
scrollTrigger: {
|
|
trigger: collectionHeader,
|
|
start: 'top 95%',
|
|
end: 'bottom 5%',
|
|
toggleActions: 'play reverse play reverse',
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
// ---- Product cards: scale + fade reveal on scroll (replays) ----
|
|
const cards = document.querySelectorAll('.product-card');
|
|
|
|
cards.forEach((card, i) => {
|
|
const imgWrap = card.querySelector('.card-img-wrap');
|
|
const img = card.querySelector('.card-img-wrap img');
|
|
const meta = card.querySelector('.card-meta');
|
|
|
|
if (!img) return;
|
|
|
|
const tl = gsap.timeline({
|
|
scrollTrigger: {
|
|
trigger: card,
|
|
start: 'top 95%',
|
|
end: 'bottom 5%',
|
|
toggleActions: 'play reverse play reverse',
|
|
},
|
|
});
|
|
|
|
// Clip-path reveal + scale + fade
|
|
tl.fromTo(imgWrap,
|
|
{ clipPath: 'inset(8% 8% 8% 8%)' },
|
|
{ clipPath: 'inset(0% 0% 0% 0%)', duration: 0.8, ease: 'power3.out' },
|
|
0
|
|
);
|
|
|
|
tl.fromTo(img,
|
|
{ opacity: 0, scale: 1.12 },
|
|
{ opacity: 1, scale: 1, duration: 0.9, ease: 'power2.out' },
|
|
0
|
|
);
|
|
|
|
if (meta) {
|
|
tl.fromTo(meta,
|
|
{ opacity: 0, y: 15 },
|
|
{ opacity: 1, y: 0, duration: 0.5, ease: 'power2.out' },
|
|
0.25
|
|
);
|
|
}
|
|
});
|
|
|
|
// ---- Newsletter section: slide in (replays) ----
|
|
const nlLeft = document.querySelector('.nl-left');
|
|
const nlRight = document.querySelector('.nl-right');
|
|
if (nlLeft && nlRight) {
|
|
gsap.fromTo(nlLeft,
|
|
{ opacity: 0, x: -40 },
|
|
{
|
|
opacity: 1, x: 0, duration: 0.7, ease: 'power2.out',
|
|
scrollTrigger: { trigger: '.newsletter', start: 'top 95%', end: 'bottom 5%', toggleActions: 'play reverse play reverse' },
|
|
}
|
|
);
|
|
gsap.fromTo(nlRight,
|
|
{ opacity: 0, x: 40 },
|
|
{
|
|
opacity: 1, x: 0, duration: 0.7, ease: 'power2.out', delay: 0.15,
|
|
scrollTrigger: { trigger: '.newsletter', start: 'top 95%', end: 'bottom 5%', toggleActions: 'play reverse play reverse' },
|
|
}
|
|
);
|
|
}
|
|
|
|
// ==========================================================
|
|
// 4. (REMOVED) — no overlay effects on panel image
|
|
// ==========================================================
|
|
|
|
// ==========================================================
|
|
// 5. PRODUCT PANEL
|
|
// ==========================================================
|
|
|
|
const panel = document.getElementById('product-panel');
|
|
const panelClose = document.getElementById('panel-close');
|
|
const panelCards = document.querySelectorAll('.product-card');
|
|
|
|
const fields = {
|
|
img: document.getElementById('panel-img'),
|
|
index: document.getElementById('panel-index'),
|
|
name: document.getElementById('panel-name'),
|
|
type: document.getElementById('panel-type'),
|
|
mat: document.getElementById('panel-mat'),
|
|
year: document.getElementById('panel-year'),
|
|
status: document.getElementById('panel-status'),
|
|
desc: document.getElementById('panel-desc'),
|
|
specs: document.getElementById('panel-specs'),
|
|
notes: document.getElementById('panel-notes'),
|
|
};
|
|
|
|
// ---- CHECKOUT LOGIC ----
|
|
const checkoutSection = document.getElementById('checkout-section');
|
|
const checkoutToggleBtn = document.getElementById('checkout-toggle-btn');
|
|
const checkoutFormWrap = document.getElementById('checkout-form-wrap');
|
|
const checkoutForm = document.getElementById('checkout-form');
|
|
const checkoutSubmitBtn = document.getElementById('checkout-submit-btn');
|
|
const checkoutPriceEl = document.querySelector('.checkout-price');
|
|
let currentSlug = null;
|
|
|
|
function formatPrice(cents) {
|
|
return (cents / 100).toLocaleString('fr-FR') + ' €';
|
|
}
|
|
|
|
if (checkoutToggleBtn) {
|
|
checkoutToggleBtn.addEventListener('click', () => {
|
|
const isOpen = checkoutFormWrap.style.display !== 'none';
|
|
checkoutFormWrap.style.display = isOpen ? 'none' : 'block';
|
|
checkoutToggleBtn.textContent = isOpen
|
|
? '[ COMMANDER CETTE PIÈCE ]'
|
|
: '[ ANNULER ]';
|
|
});
|
|
}
|
|
|
|
if (checkoutForm) {
|
|
checkoutForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
if (!currentSlug) return;
|
|
const email = document.getElementById('checkout-email').value;
|
|
|
|
checkoutSubmitBtn.disabled = true;
|
|
checkoutSubmitBtn.textContent = 'CONNEXION STRIPE...';
|
|
|
|
try {
|
|
const res = await fetch('/api/checkout', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ product: currentSlug, email }),
|
|
});
|
|
const data = await res.json();
|
|
if (data.url) {
|
|
window.location.href = data.url;
|
|
} else {
|
|
throw new Error('No URL returned');
|
|
}
|
|
} catch (err) {
|
|
checkoutSubmitBtn.disabled = false;
|
|
checkoutSubmitBtn.textContent = 'ERREUR — RÉESSAYER';
|
|
console.error(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function toSlug(name) {
|
|
return name
|
|
.toLowerCase()
|
|
.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
|
.replace(/_/g, '-')
|
|
.replace(/[^a-z0-9-]/g, '');
|
|
}
|
|
|
|
function openPanel(card, pushState = true) {
|
|
fields.img.src = card.dataset.img;
|
|
fields.img.alt = card.dataset.imgAlt || card.dataset.name;
|
|
fields.index.textContent = card.dataset.index;
|
|
fields.name.textContent = card.dataset.name;
|
|
fields.type.textContent = card.dataset.type;
|
|
fields.mat.textContent = card.dataset.mat;
|
|
fields.year.textContent = card.dataset.year;
|
|
fields.status.textContent = card.dataset.status;
|
|
fields.desc.textContent = card.dataset.desc;
|
|
fields.specs.textContent = card.dataset.specs;
|
|
fields.notes.textContent = card.dataset.notes;
|
|
|
|
// Checkout
|
|
const price = card.dataset.price;
|
|
const slug = card.dataset.slug;
|
|
const isOrderable = price && slug;
|
|
|
|
checkoutSection.style.display = 'block';
|
|
|
|
if (isOrderable) {
|
|
currentSlug = slug;
|
|
checkoutPriceEl.textContent = formatPrice(parseInt(price, 10));
|
|
checkoutToggleBtn.textContent = '[ COMMANDER CETTE PIÈCE ]';
|
|
checkoutToggleBtn.disabled = false;
|
|
checkoutToggleBtn.classList.remove('checkout-btn--disabled');
|
|
} else {
|
|
currentSlug = null;
|
|
checkoutPriceEl.textContent = '';
|
|
checkoutToggleBtn.textContent = 'PROCHAINEMENT DISPONIBLE';
|
|
checkoutToggleBtn.disabled = true;
|
|
checkoutToggleBtn.classList.add('checkout-btn--disabled');
|
|
}
|
|
|
|
checkoutFormWrap.style.display = 'none';
|
|
checkoutSubmitBtn.disabled = false;
|
|
checkoutSubmitBtn.textContent = 'PROCÉDER AU PAIEMENT →';
|
|
checkoutForm.reset();
|
|
|
|
panel.querySelectorAll('details').forEach(d => d.setAttribute('open', ''));
|
|
panel.classList.add('is-open');
|
|
panel.setAttribute('aria-hidden', 'false');
|
|
document.body.style.overflow = 'hidden';
|
|
|
|
attachCursorHover(panel.querySelectorAll(
|
|
'summary, .panel-close, .checkout-btn, .checkout-submit'
|
|
));
|
|
|
|
if (pushState) {
|
|
const cardSlug = card.dataset.slug || toSlug(card.dataset.name);
|
|
history.pushState({ slug: cardSlug }, '', `/collection/${cardSlug}`);
|
|
}
|
|
}
|
|
|
|
function closePanel(pushState = true) {
|
|
panel.classList.remove('is-open');
|
|
panel.setAttribute('aria-hidden', 'true');
|
|
document.body.style.overflow = '';
|
|
|
|
if (pushState) {
|
|
history.pushState({}, '', '/');
|
|
}
|
|
}
|
|
|
|
panelCards.forEach(card => {
|
|
card.addEventListener('click', () => openPanel(card));
|
|
});
|
|
|
|
// Auto-open from direct URL (/collection/[slug])
|
|
if (window.__OPEN_PANEL__) {
|
|
const name = window.__OPEN_PANEL__;
|
|
const card = [...panelCards].find(c => c.dataset.name === name);
|
|
if (card) openPanel(card, false);
|
|
}
|
|
|
|
if (panelClose) panelClose.addEventListener('click', () => closePanel());
|
|
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') closePanel();
|
|
});
|
|
|
|
window.addEventListener('popstate', () => {
|
|
if (panel.classList.contains('is-open')) {
|
|
closePanel(false);
|
|
} else {
|
|
const match = location.pathname.match(/^\/collection\/(.+)$/);
|
|
if (match) {
|
|
const slug = match[1];
|
|
const card = [...panelCards].find(c => c.dataset.slug === slug || toSlug(c.dataset.name) === slug);
|
|
if (card) openPanel(card, false);
|
|
}
|
|
}
|
|
});
|
|
|
|
// ==========================================================
|
|
// 6. AMBIENT WORKSHOP SOUND (MP3)
|
|
// ==========================================================
|
|
|
|
let soundOn = true;
|
|
|
|
// Create audio element (preloaded, looped, low volume)
|
|
const ambientAudio = new Audio('/assets/atelier-ambiance.mp3');
|
|
ambientAudio.loop = true;
|
|
ambientAudio.volume = 0;
|
|
ambientAudio.preload = 'auto';
|
|
|
|
const headerNav = document.querySelector('.header-nav');
|
|
if (headerNav) {
|
|
const soundBtn = document.createElement('button');
|
|
soundBtn.className = 'sound-toggle sound-active';
|
|
soundBtn.setAttribute('aria-label', 'Couper le son ambiant');
|
|
soundBtn.innerHTML =
|
|
'<span class="sound-bars">' +
|
|
'<span class="sound-bar"></span>' +
|
|
'<span class="sound-bar"></span>' +
|
|
'<span class="sound-bar"></span>' +
|
|
'</span>' +
|
|
'<span class="sound-label">SON</span>';
|
|
soundBtn.addEventListener('click', toggleSound);
|
|
headerNav.appendChild(soundBtn);
|
|
attachCursorHover([soundBtn]);
|
|
}
|
|
|
|
// Autoplay on first user interaction (browsers require it)
|
|
let autoStarted = false;
|
|
function autoStartSound() {
|
|
if (autoStarted || !soundOn) return;
|
|
autoStarted = true;
|
|
startAmbientSound();
|
|
window.removeEventListener('click', autoStartSound);
|
|
window.removeEventListener('scroll', autoStartSound);
|
|
window.removeEventListener('mousemove', autoStartSound);
|
|
}
|
|
window.addEventListener('click', autoStartSound, { once: false });
|
|
window.addEventListener('scroll', autoStartSound, { once: false });
|
|
window.addEventListener('mousemove', autoStartSound, { once: false });
|
|
|
|
// Smooth volume fade using GSAP
|
|
function startAmbientSound() {
|
|
ambientAudio.play().then(() => {
|
|
gsap.to(ambientAudio, { volume: 0.04, duration: 2, ease: 'power2.out' });
|
|
}).catch(() => {});
|
|
}
|
|
|
|
function stopAmbientSound() {
|
|
gsap.to(ambientAudio, {
|
|
volume: 0, duration: 1.2, ease: 'power2.in',
|
|
onComplete: () => ambientAudio.pause(),
|
|
});
|
|
}
|
|
|
|
function toggleSound() {
|
|
soundOn = !soundOn;
|
|
const btn = document.querySelector('.sound-toggle');
|
|
if (!btn) return;
|
|
|
|
if (soundOn) {
|
|
startAmbientSound();
|
|
btn.classList.add('sound-active');
|
|
btn.setAttribute('aria-label', 'Couper le son ambiant');
|
|
} else {
|
|
stopAmbientSound();
|
|
btn.classList.remove('sound-active');
|
|
btn.setAttribute('aria-label', 'Activer le son ambiant');
|
|
}
|
|
}
|
|
|
|
// ==========================================================
|
|
// 7. CONTACT MODAL
|
|
// ==========================================================
|
|
|
|
const contactModal = document.getElementById('contact-modal');
|
|
const contactForm = document.getElementById('contact-form');
|
|
|
|
function openContactModal() {
|
|
if (!contactModal) return;
|
|
contactModal.classList.add('is-open');
|
|
contactModal.setAttribute('aria-hidden', 'false');
|
|
document.body.style.overflow = 'hidden';
|
|
attachCursorHover(contactModal.querySelectorAll('button, input, textarea'));
|
|
}
|
|
|
|
function closeContactModal() {
|
|
if (!contactModal) return;
|
|
contactModal.classList.remove('is-open');
|
|
contactModal.setAttribute('aria-hidden', 'true');
|
|
if (!panel.classList.contains('is-open')) {
|
|
document.body.style.overflow = '';
|
|
}
|
|
}
|
|
|
|
// Trigger links
|
|
document.querySelectorAll('.contact-trigger').forEach(link => {
|
|
link.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
openContactModal();
|
|
});
|
|
});
|
|
|
|
// Close button
|
|
const contactCloseBtn = contactModal?.querySelector('.contact-modal-close');
|
|
if (contactCloseBtn) contactCloseBtn.addEventListener('click', closeContactModal);
|
|
|
|
// Backdrop click
|
|
const contactBackdrop = contactModal?.querySelector('.contact-modal-backdrop');
|
|
if (contactBackdrop) contactBackdrop.addEventListener('click', closeContactModal);
|
|
|
|
// Escape key
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && contactModal?.classList.contains('is-open')) {
|
|
closeContactModal();
|
|
}
|
|
});
|
|
|
|
// Form → WhatsApp
|
|
if (contactForm) {
|
|
contactForm.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
const name = document.getElementById('contact-name').value.trim();
|
|
const email = document.getElementById('contact-email').value.trim();
|
|
const subject = document.getElementById('contact-subject').value.trim() || 'Contact depuis rebours.studio';
|
|
const message = document.getElementById('contact-message').value.trim();
|
|
|
|
const text = `*${subject}*\n\n${message}\n\n— ${name}\n${email}`;
|
|
window.open(`https://wa.me/33651755191?text=${encodeURIComponent(text)}`, '_blank');
|
|
});
|
|
}
|
|
|
|
});
|