Enhance contact page response modal with improved styling and functionality

- Updated the response modal layout for better visibility and user experience, including a full-screen overlay and refined content container.
- Enhanced the success message display with new animations and decorative elements.
- Improved CSS styles for better readability and aesthetics, including adjustments to headings, paragraphs, and links.
- Added functionality to close the modal when clicking outside of it for improved usability.
This commit is contained in:
Nicholai 2025-12-08 01:07:03 -07:00
parent bcbb67a822
commit 2d389ed8df

View File

@ -229,29 +229,38 @@ const pageTitle = `Contact | ${SITE_TITLE}`;
</div>
<!-- Response State (hidden initially) -->
<div id="response-state" class="hidden w-full max-w-4xl mx-auto px-6 opacity-0 transform scale-95 transition-all duration-700">
<div id="response-state" class="hidden w-full h-full absolute inset-0 z-10 flex flex-col items-center justify-center p-6 opacity-0 transition-all duration-700">
<!-- Close button -->
<button id="close-modal" class="absolute top-8 right-8 p-3 border border-white/20 hover:border-brand-accent hover:bg-brand-accent/10 transition-all duration-300 group">
<button id="close-modal" class="absolute top-8 right-8 z-50 p-3 border border-white/20 hover:border-brand-accent hover:bg-brand-accent/10 transition-all duration-300 group">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-white group-hover:text-brand-accent transition-colors">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
<!-- Success indicator -->
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-20 h-20 border-2 border-brand-accent rounded-full mb-6 animate-scale-in">
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="text-brand-accent">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
<!-- Content Container -->
<div class="w-full max-w-5xl mx-auto flex flex-col items-center relative">
<!-- Header - More subtle now -->
<div class="text-center mb-12 animate-scale-in">
<div class="flex items-center justify-center gap-3 mb-4">
<span class="w-2 h-2 bg-brand-accent rounded-full animate-pulse"></span>
<p class="font-mono text-sm text-brand-accent uppercase tracking-widest">Transmission Received</p>
<span class="w-2 h-2 bg-brand-accent rounded-full animate-pulse"></span>
</div>
</div>
<h2 class="text-4xl md:text-6xl font-bold text-white uppercase tracking-tight mb-3">Transmission Received</h2>
<p class="font-mono text-sm text-brand-accent uppercase tracking-widest">Signal Confirmed</p>
</div>
<!-- Response content with better styling -->
<div class="bg-gradient-to-br from-brand-dark/80 to-brand-dark/60 border border-brand-accent/40 p-10 md:p-16 backdrop-blur-sm max-h-[65vh] overflow-y-auto custom-scrollbar shadow-2xl">
<div id="response-content" class="prose-response"></div>
<!-- Response content - The Focal Point -->
<div class="w-full relative">
<!-- Decorative corner markers -->
<div class="absolute -top-4 -left-4 w-8 h-8 border-t-2 border-l-2 border-brand-accent opacity-50"></div>
<div class="absolute -top-4 -right-4 w-8 h-8 border-t-2 border-r-2 border-brand-accent opacity-50"></div>
<div class="absolute -bottom-4 -left-4 w-8 h-8 border-b-2 border-l-2 border-brand-accent opacity-50"></div>
<div class="absolute -bottom-4 -right-4 w-8 h-8 border-b-2 border-r-2 border-brand-accent opacity-50"></div>
<!-- Content -->
<div id="response-content" class="prose-response max-h-[70vh] overflow-y-auto custom-scrollbar px-4 md:px-8 py-4"></div>
</div>
</div>
</div>
</div>
@ -344,118 +353,93 @@ const pageTitle = `Contact | ${SITE_TITLE}`;
/* Response Content Prose Styles - Enhanced Readability */
.prose-response {
color: white;
text-align: left;
}
.prose-response h1,
.prose-response h2,
.prose-response h3 {
color: #00FFFF;
color: white;
margin-top: 1.5em;
margin-bottom: 0.75em;
font-weight: 700;
line-height: 1.3;
font-weight: 800;
line-height: 1.1;
letter-spacing: -0.02em;
}
.prose-response h1 {
font-size: 2.5em;
text-transform: uppercase;
}
.prose-response h1 {
font-size: 3.5rem;
background: linear-gradient(to right, #fff, #94a3b8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 0.5em;
}
.prose-response h2 {
font-size: 1.875em;
font-size: 2.5rem;
}
.prose-response h3 {
font-size: 1.5em;
}
.prose-response h1:first-child,
.prose-response h2:first-child,
.prose-response h3:first-child {
margin-top: 0;
font-size: 1.75rem;
color: #ff4d00;
}
.prose-response p {
margin-bottom: 1.25em;
line-height: 2;
color: rgba(255, 255, 255, 0.95);
font-size: 1.125rem;
margin-bottom: 1.5em;
line-height: 1.8;
color: rgba(255, 255, 255, 0.9);
font-size: 1.5rem; /* Increased size significantly */
font-weight: 300;
max-width: 65ch;
margin-right: auto;
}
.prose-response strong {
color: #00FFFF;
font-weight: 700;
font-size: 1.05em;
color: #ff4d00;
font-weight: 600;
}
.prose-response em {
font-style: italic;
color: rgba(0, 255, 255, 0.9);
font-weight: 400;
color: #94a3b8;
}
/* Blockquote for signature or special text */
.prose-response blockquote {
border-left: none; /* Removed standard border */
margin: 3em 0 1em;
padding: 0;
color: #ff4d00;
font-family: 'Courier New', monospace;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0.2em;
display: inline-block;
border-top: 1px solid rgba(255, 77, 0, 0.3);
padding-top: 2em;
}
.prose-response a {
color: #00FFFF;
color: #ff4d00;
text-decoration: underline;
text-underline-offset: 4px;
text-decoration-thickness: 2px;
transition: all 0.3s;
font-weight: 500;
}
.prose-response a:hover {
opacity: 0.7;
text-decoration-thickness: 3px;
color: white;
text-decoration-thickness: 2px;
}
.prose-response ul,
.prose-response ol {
margin-bottom: 1.5em;
padding-left: 1.75em;
}
.prose-response li {
margin-bottom: 0.75em;
line-height: 1.9;
color: rgba(255, 255, 255, 0.9);
font-size: 1.0625rem;
}
.prose-response code {
background: rgba(0, 255, 255, 0.15);
padding: 0.3em 0.5em;
border-radius: 4px;
font-size: 0.95em;
color: #00FFFF;
font-family: 'Courier New', monospace;
border: 1px solid rgba(0, 255, 255, 0.2);
}
.prose-response pre {
background: rgba(0, 0, 0, 0.4);
padding: 1.5em;
border-radius: 6px;
overflow-x: auto;
margin-bottom: 1.5em;
border: 1px solid rgba(0, 255, 255, 0.2);
}
.prose-response blockquote {
border-left: 4px solid #00FFFF;
padding-left: 1.5em;
margin: 1.5em 0;
color: rgba(255, 255, 255, 0.8);
font-style: italic;
font-size: 1.125rem;
line-height: 1.9;
}
.prose-response hr {
border: none;
border-top: 1px solid rgba(0, 255, 255, 0.3);
margin: 2em 0;
/* Mobile adjustments */
@media (max-width: 768px) {
.prose-response h1 {
font-size: 2.5rem;
}
.prose-response p {
font-size: 1.125rem;
}
}
</style>
@ -613,6 +597,21 @@ const pageTitle = `Contact | ${SITE_TITLE}`;
closeModalBtn.addEventListener('click', closeModal);
}
// Close on click outside
if (transmissionModal) {
transmissionModal.addEventListener('click', (e) => {
const target = e.target as HTMLElement;
// Only close if response state is active and visible
// We check if the click target is the container itself (the background)
// response-state covers the whole screen when active
if (!responseState.classList.contains('hidden') &&
(target === responseState || target === transmissionModal)) {
closeModal();
}
});
}
// ===== Form Submission Handler =====
const contactForm = document.getElementById('contact-form') as HTMLFormElement;
const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement;