feat: implement a contact modal with form submission functionality and minor style adjustments to card tags.

This commit is contained in:
ordinarthur 2026-03-20 22:57:23 +01:00
parent 801342a0bd
commit 338efc548e
4 changed files with 261 additions and 9 deletions

View File

@ -787,15 +787,15 @@ hr { border: none; border-top: var(--border); margin: 0; }
.card-coord-tag { .card-coord-tag {
position: absolute; position: absolute;
bottom: 6px; left: 8px; bottom: 8px; left: 10px;
font-family: var(--font-mono); font-family: var(--font-mono);
font-size: 0.45rem; font-size: 0.58rem;
color: rgba(232,168,0,0.6); color: rgba(232,168,0,0.9);
letter-spacing: 0.05em; letter-spacing: 0.05em;
z-index: 5; z-index: 5;
pointer-events: none; pointer-events: none;
background: rgba(0,0,0,0.35); background: #111;
padding: 1px 5px; padding: 2px 7px;
} }
/* Construction line under collection header */ /* Construction line under collection header */
@ -861,6 +861,126 @@ hr { border: none; border-top: var(--border); margin: 0; }
100% { height: 10px; } 100% { height: 10px; }
} }
/* ---- CONTACT MODAL ---- */
.contact-modal {
position: fixed;
inset: 0;
z-index: 1001;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.contact-modal.is-open {
opacity: 1;
pointer-events: auto;
}
.contact-modal-backdrop {
position: absolute;
inset: 0;
background: rgba(0,0,0,0.6);
}
.contact-modal-content {
position: relative;
background: var(--clr-bg);
border: 2px solid var(--clr-black);
width: 90%;
max-width: 480px;
max-height: 90vh;
overflow-y: auto;
padding: 2rem;
display: flex;
flex-direction: column;
gap: 1.2rem;
pointer-events: auto;
}
.contact-modal-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.contact-modal-close {
background: none;
border: 1px solid var(--clr-black);
font-family: var(--font-mono);
font-size: 0.85rem;
width: 32px; height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: none;
pointer-events: auto;
transition: background 0.15s, color 0.15s;
}
.contact-modal-close:hover {
background: var(--clr-black);
color: var(--clr-white);
}
.contact-modal-title {
font-size: clamp(1.6rem, 3vw, 2.2rem);
font-weight: 700;
line-height: 1;
letter-spacing: -0.01em;
}
.contact-form {
display: flex;
flex-direction: column;
gap: 0;
}
.contact-field {
display: flex;
flex-direction: column;
gap: 0.3rem;
padding: 0.8rem 0;
border-bottom: 1px solid rgba(0,0,0,0.12);
}
.contact-field label {
font-size: 0.68rem;
font-weight: 700;
color: #555;
letter-spacing: 0.05em;
}
.contact-field input,
.contact-field textarea {
border: none;
background: transparent;
font-family: var(--font-mono);
font-size: 0.82rem;
outline: none;
cursor: none;
padding: 0;
color: var(--clr-black);
pointer-events: auto;
resize: vertical;
}
.contact-field input::placeholder,
.contact-field textarea::placeholder { color: #aaa; }
.contact-submit {
margin-top: 1rem;
background: var(--clr-black);
color: #e8a800;
border: none;
font-family: var(--font-mono);
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.04em;
padding: 1.1rem 1.5rem;
cursor: none;
text-align: center;
transition: background 0.15s, color 0.15s;
pointer-events: auto;
}
.contact-submit:hover {
background: #e8a800;
color: var(--clr-black);
}
.contact-note {
margin-top: 0.6rem;
text-align: center;
}
/* ---- RESPONSIVE ---- */ /* ---- RESPONSIVE ---- */
@media (max-width: 900px) { @media (max-width: 900px) {
.hero, .newsletter { grid-template-columns: 1fr; } .hero, .newsletter { grid-template-columns: 1fr; }

View File

@ -166,7 +166,7 @@ const schemaBreadcrumb = {
<a href="/" class="logo-text" aria-label="REBOURS — Accueil">REBOURS</a> <a href="/" class="logo-text" aria-label="REBOURS — Accueil">REBOURS</a>
<nav class="header-nav" aria-label="Navigation principale"> <nav class="header-nav" aria-label="Navigation principale">
<a href="/#collection">COLLECTION_001</a> <a href="/#collection">COLLECTION_001</a>
<a href="/#contact">CONTACT</a> <a href="#" class="contact-trigger">CONTACT</a>
<span class="wip-tag"><span class="blink">■</span> W.I.P</span> <span class="wip-tag"><span class="blink">■</span> W.I.P</span>
</nav> </nav>
</header> </header>
@ -255,12 +255,47 @@ const schemaBreadcrumb = {
<nav aria-label="Liens secondaires"> <nav aria-label="Liens secondaires">
<a href="https://instagram.com/rebour.studio" rel="noopener" target="_blank">INSTAGRAM</a> <a href="https://instagram.com/rebour.studio" rel="noopener" target="_blank">INSTAGRAM</a>
&nbsp;/&nbsp; &nbsp;/&nbsp;
<a href="mailto:contact@rebour.studio">CONTACT</a> <a href="#" class="contact-trigger">CONTACT</a>
</nav> </nav>
</footer> </footer>
</div> </div>
<!-- CONTACT MODAL -->
<div id="contact-modal" class="contact-modal" aria-hidden="true">
<div class="contact-modal-backdrop"></div>
<div class="contact-modal-content">
<div class="contact-modal-header">
<p class="label">// CONTACT</p>
<button class="contact-modal-close" aria-label="Fermer">✕</button>
</div>
<hr>
<h2 class="contact-modal-title">ENVOYER<br>UN MESSAGE</h2>
<form id="contact-form" class="contact-form">
<div class="contact-field">
<label for="contact-name">NOM *</label>
<input type="text" id="contact-name" name="name" placeholder="Votre nom" required autocomplete="name">
</div>
<div class="contact-field">
<label for="contact-email">EMAIL *</label>
<input type="email" id="contact-email" name="email" placeholder="votre@email.com" required autocomplete="email">
</div>
<div class="contact-field">
<label for="contact-subject">OBJET</label>
<input type="text" id="contact-subject" name="subject" placeholder="Objet du message" autocomplete="off">
</div>
<div class="contact-field">
<label for="contact-message">MESSAGE *</label>
<textarea id="contact-message" name="message" rows="5" placeholder="Votre message..." required></textarea>
</div>
<button type="submit" class="contact-submit">
ENVOYER LE MESSAGE →
</button>
<p class="mono-sm contact-note"><span class="blink">■</span> REDIRECTION VERS VOTRE CLIENT MAIL</p>
</form>
</div>
</div>
<div class="cursor-dot"></div> <div class="cursor-dot"></div>
<div class="cursor-outline"></div> <div class="cursor-outline"></div>
</Base> </Base>

View File

@ -130,7 +130,7 @@ const schemaOrg = {
<a href="/" class="logo-text" aria-label="REBOURS — Accueil">REBOURS</a> <a href="/" class="logo-text" aria-label="REBOURS — Accueil">REBOURS</a>
<nav class="header-nav" aria-label="Navigation principale"> <nav class="header-nav" aria-label="Navigation principale">
<a href="#collection">COLLECTION_001</a> <a href="#collection">COLLECTION_001</a>
<a href="#contact">CONTACT</a> <a href="#" class="contact-trigger">CONTACT</a>
<span class="wip-tag"><span class="blink">■</span> W.I.P</span> <span class="wip-tag"><span class="blink">■</span> W.I.P</span>
</nav> </nav>
</header> </header>
@ -222,12 +222,47 @@ const schemaOrg = {
<nav aria-label="Liens secondaires"> <nav aria-label="Liens secondaires">
<a href="https://instagram.com/rebour.studio" rel="noopener" target="_blank">INSTAGRAM</a> <a href="https://instagram.com/rebour.studio" rel="noopener" target="_blank">INSTAGRAM</a>
&nbsp;/&nbsp; &nbsp;/&nbsp;
<a href="mailto:contact@rebour.studio">CONTACT</a> <a href="#" class="contact-trigger">CONTACT</a>
</nav> </nav>
</footer> </footer>
</div> </div>
<!-- CONTACT MODAL -->
<div id="contact-modal" class="contact-modal" aria-hidden="true">
<div class="contact-modal-backdrop"></div>
<div class="contact-modal-content">
<div class="contact-modal-header">
<p class="label">// CONTACT</p>
<button class="contact-modal-close" aria-label="Fermer">✕</button>
</div>
<hr>
<h2 class="contact-modal-title">ENVOYER<br>UN MESSAGE</h2>
<form id="contact-form" class="contact-form">
<div class="contact-field">
<label for="contact-name">NOM *</label>
<input type="text" id="contact-name" name="name" placeholder="Votre nom" required autocomplete="name">
</div>
<div class="contact-field">
<label for="contact-email">EMAIL *</label>
<input type="email" id="contact-email" name="email" placeholder="votre@email.com" required autocomplete="email">
</div>
<div class="contact-field">
<label for="contact-subject">OBJET</label>
<input type="text" id="contact-subject" name="subject" placeholder="Objet du message" autocomplete="off">
</div>
<div class="contact-field">
<label for="contact-message">MESSAGE *</label>
<textarea id="contact-message" name="message" rows="5" placeholder="Votre message..." required></textarea>
</div>
<button type="submit" class="contact-submit">
ENVOYER LE MESSAGE →
</button>
<p class="mono-sm contact-note"><span class="blink">■</span> REDIRECTION VERS VOTRE CLIENT MAIL</p>
</form>
</div>
</div>
<div class="cursor-dot"></div> <div class="cursor-dot"></div>
<div class="cursor-outline"></div> <div class="cursor-outline"></div>
</Base> </Base>

View File

@ -660,4 +660,66 @@ document.addEventListener('DOMContentLoaded', () => {
} }
} }
// ==========================================================
// 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 → mailto
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 body = `${message}\n\n${name}\n${email}`;
const mailto = `mailto:contact@rebours.fr?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
window.location.href = mailto;
});
}
}); });