portfolio-page/src/scss/sections/contact-section.scss

841 lines
16 KiB
SCSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@use '../globals';
@use '../variables' as *;
@use '../mixins' as *;
.contact-section {
background: var(--contact-background);
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(
90deg,
transparent 0%,
var(--color-primary) 30%,
var(--color-secondary) 70%,
transparent 100%
);
}
&__container {
@include section-container;
}
&__header {
@include section-header;
}
&__title {
@include section-title;
font-size: clamp(2rem, 5vw, 2.75rem);
font-weight: 800;
}
&__subtitle {
@include section-subtitle;
}
&__grid {
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
'connect'
'sidebar'
'social';
gap: 3rem;
align-items: start;
@include globals.desktop-only {
grid-template-columns: 2fr 1fr;
grid-template-areas:
'connect sidebar'
'social .';
gap: 4rem;
align-items: stretch;
}
}
// Connect Card
&__connect-card {
grid-area: connect;
background: var(--form-background);
border-radius: var(--card-border-radius);
padding: var(--card-padding);
transition: var(--transition-default);
display: flex;
flex-direction: column;
}
&__connect-header {
display: flex;
gap: 1rem;
margin-bottom: 2rem;
align-items: flex-start;
}
&__connect-text {
flex: 1;
}
&__email-icon {
width: 2rem;
height: 2rem;
color: var(
--color-primary
); // #042C53 light / #E6F1FB dark high contrast in both
background: rgba(4, 44, 83, 0.08);
border-radius: 0.75rem;
padding: 0.5rem;
flex-shrink: 0;
}
&__email-title {
font-size: 1.5rem;
font-weight: 700;
color: $color-heading;
margin-bottom: 0.75rem;
}
&__email-description {
color: var(--color-text-muted);
font-size: 1rem;
line-height: 1.6;
margin-bottom: 1.5rem;
}
&__appointment-hint {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
padding: 0.75rem 1rem;
margin-bottom: 1.5rem;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 0.75rem;
font-size: 0.9rem;
}
&__appointment-icon {
width: 1.125rem;
height: 1.125rem;
color: var(--color-primary);
flex-shrink: 0;
}
&__appointment-text {
color: var(--color-text-muted);
}
&__appointment-link {
color: var(--color-primary);
font-weight: 500;
text-decoration: underline;
text-underline-offset: 3px;
transition: color var(--transition-fast);
white-space: nowrap;
&:hover {
color: var(--color-primary-hover, var(--color-primary));
}
&:focus {
outline: 2px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
border-radius: 2px;
}
}
// Social Card - positioned below connect card
&__social-card {
grid-area: social;
background: var(--form-background);
border: 1px solid var(--form-border);
border-radius: var(--card-border-radius);
padding: var(--card-padding);
}
&__social-title {
font-size: 1.125rem;
font-weight: 600;
color: var(--color-text);
margin-bottom: var(--card-padding-sm);
}
&__social-list {
display: flex;
flex-direction: column;
gap: var(--card-gap-sm);
}
// Sidebar
&__sidebar {
grid-area: sidebar;
display: flex;
flex-direction: column;
height: 100%;
}
&__info-card {
background: var(--form-background);
border: 1px solid var(--form-border);
border-radius: var(--card-border-radius);
padding: var(--card-padding);
flex: 1;
display: flex;
flex-direction: column;
}
&__availability {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: var(--card-padding);
padding: var(--card-gap-sm);
background: rgba(34, 197, 94, 0.1);
border: 1px solid rgba(34, 197, 94, 0.2);
border-radius: 0.75rem;
}
&__status-indicator {
width: 0.75rem;
height: 0.75rem;
background: #22c55e;
border-radius: 50%;
flex-shrink: 0;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
&__status-text {
font-size: 0.875rem;
font-weight: 500;
color: #065f46; // dark emerald 7.4:1 on white; light-mode accessible
[data-theme='dark'] & {
color: #34d399; // light mint high contrast on dark bg
}
}
&__quick-facts {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
&__fact {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
&__fact-label {
font-size: 0.75rem;
color: var(--color-text-muted);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
}
&__fact-value {
font-size: 0.875rem;
color: var(--color-text);
font-weight: 500;
}
// Contact Info Section
&__info {
display: flex;
flex-direction: column;
gap: 2rem;
}
&__connect-title {
font-size: 1.5rem;
font-weight: 600;
color: var(--color-text);
margin-bottom: 1.5rem;
}
&__connect-description {
color: var(--color-text-muted);
line-height: 1.6;
margin-bottom: 2rem;
}
&__details {
display: flex;
flex-direction: column;
gap: 1rem;
}
&__detail-item {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1rem;
}
&__detail-icon {
width: 1.25rem;
height: 1.25rem;
color: var(--color-contact-primary);
flex-shrink: 0;
}
&__detail-text {
color: var(--color-text);
font-size: 0.875rem;
}
&__detail-link {
color: var(--color-primary);
font-size: 0.875rem;
font-weight: 500;
text-decoration: underline;
text-underline-offset: 3px;
transition: color var(--transition-fast);
&:hover {
color: var(--color-primary-hover, var(--color-primary));
}
&:focus {
outline: 2px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
border-radius: 2px;
}
}
&__social {
display: flex;
gap: 1rem;
margin-top: 1rem;
}
&__social-button {
display: flex;
align-items: center;
justify-content: center;
width: 2.5rem;
height: 2.5rem;
border: 1px solid var(--contact-social-border);
border-radius: 0.375rem;
background: var(--contact-social-bg);
color: var(--contact-social-text);
text-decoration: none;
transition: all 0.2s ease;
cursor: pointer;
&:hover {
background: var(--contact-social-hover-bg);
border-color: var(--contact-social-hover-border);
transform: translateY(-1px);
}
// Enhanced focus states for AAA compliance
&:focus {
outline: 3px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
}
// Icons inherit color from parent button's var(--contact-social-text)
// which is #042C53 (light) / #E6F1FB (dark) both high contrast
.contact-section__social-icon {
color: currentColor;
}
}
&__social-icon {
width: 1rem;
height: 1rem;
}
// Contact Form Section
&__form-card {
background: var(--contact-form-bg);
border: 1px solid var(--contact-form-border);
border-radius: 1rem;
box-shadow: var(--contact-form-shadow);
overflow: hidden;
}
&__form-header {
padding: 1.5rem 1.5rem 0;
margin-bottom: 1.5rem;
}
&__form-title {
font-size: 1.25rem;
font-weight: 600;
color: var(--color-text);
margin-bottom: 0.5rem;
}
&__form-description {
color: var(--color-text-muted);
font-size: 0.875rem;
}
// Status Message Styles
&__status {
padding: 0.75rem 1rem;
border-radius: 0.5rem;
margin-bottom: 1rem;
font-size: 0.875rem;
font-weight: 500;
&--success {
background-color: var(--contact-status-success-bg);
border: 1px solid var(--contact-status-success-border);
color: var(--contact-status-success-text);
}
&--error {
background-color: var(--contact-status-error-bg);
border: 1px solid var(--contact-status-error-border);
color: var(--contact-status-error-text);
}
}
&__status-message {
margin: 0;
line-height: 1.4;
}
&__form {
padding: 0 1.5rem 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
// Honeypot field - hidden from users but visible to bots
&__honeypot {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
opacity: 0;
}
&__honeypot-label,
&__honeypot-input {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
opacity: 0;
}
&__form-row {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
@include globals.mobile-only {
grid-template-columns: 1fr 1fr;
}
}
&__form-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
&__form-label {
font-size: 0.875rem;
font-weight: 500;
color: var(--color-text);
}
&__form-input,
&__form-textarea {
padding: 0.75rem;
border: 1px solid var(--contact-input-border);
border-radius: 0.375rem;
background: var(--contact-input-bg);
color: var(--color-text);
font-size: 0.875rem;
transition: all 0.2s ease;
&::placeholder {
color: var(--color-text-muted);
}
&:focus {
outline: none;
border-color: var(--color-contact-primary);
box-shadow: 0 0 0 3px var(--contact-input-focus-ring);
}
}
&__form-textarea {
resize: vertical;
min-height: 5rem;
font-family: inherit;
}
&__form-button {
background: var(--contact-button-bg);
color: var(--contact-button-text);
border: none;
border-radius: 0.375rem;
padding: 0.75rem 1.5rem;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
margin-top: 0.5rem;
&:hover:not(:disabled) {
background: var(--contact-button-hover-bg);
transform: translateY(-1px);
}
&:active:not(:disabled) {
transform: translateY(0);
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
}
// Responsive adjustments
@include globals.mobile-only {
&__grid {
gap: 2rem;
}
&__form-card,
&__email-card {
border-radius: 0.75rem;
}
&__form-header,
&__form,
&__email-header {
padding-left: 1rem;
padding-right: 1rem;
}
&__social {
justify-content: center;
margin-top: 1.5rem;
}
}
// Email Button Card Styles
&__email-card {
background: var(--form-background);
border-radius: 1rem;
border: 1px solid var(--form-border);
padding: 2rem;
text-align: center;
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
&:hover {
box-shadow:
0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform: translateY(-2px);
}
}
&__email-header {
margin-bottom: 2rem;
padding: 0;
}
&__email-card-icon {
width: 3rem;
height: 3rem;
color: var(--color-primary); // #042C53 light / #E6F1FB dark high contrast
margin: 0 auto 1rem;
display: block;
}
&__email-button {
background: var(--contact-button-bg);
border: none;
border-radius: 0.75rem;
padding: 1rem 2rem;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.75rem;
margin: var(--card-padding-sm) 0;
text-decoration: none;
color: var(--contact-button-text);
box-shadow: none;
width: 100%;
position: relative;
overflow: hidden;
&::before {
display: none;
}
&:hover {
background: var(--contact-button-hover-bg);
transform: translateY(-2px);
box-shadow: none;
}
&:active {
transform: translateY(-1px);
}
}
&__button-text {
font-weight: 600;
font-size: 1.1rem;
}
&__button-icon {
width: 1.25rem;
height: 1.25rem;
}
&__email-info {
margin-top: 1.5rem;
}
&__email-note {
font-size: 0.875rem;
color: var(--text-secondary);
line-height: 1.5;
strong {
color: var(--color-primary);
font-weight: 600;
}
}
}
// Mobile responsive adjustments
@include globals.mobile-only {
.contact-section {
&__grid {
gap: 2rem;
}
&__connect-card {
margin-bottom: 0.5rem;
}
&__social-card {
margin-top: 0.5rem;
}
&__email-button {
padding: 0.875rem 1.5rem;
font-size: 1rem;
}
&__email-icon {
width: 1.5rem;
height: 1.5rem;
padding: 0.375rem;
}
&__email-title {
font-size: 1.25rem;
}
&__connect-header {
margin-bottom: 1.5rem;
}
&__email-description {
margin-bottom: 1.5rem;
}
}
}
// Add these accessibility enhancements:
// Screen reader only classes
.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
.sr-only-focusable:focus {
position: static !important;
width: auto !important;
height: auto !important;
padding: 0.5rem !important;
margin: 0 !important;
overflow: visible !important;
clip: auto !important;
white-space: normal !important;
background-color: var(--contact-button-bg) !important;
color: var(--contact-button-text) !important;
// Enhanced focus states for AAA compliance
&:focus {
outline: 3px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
}
}
// Fact list styling for proper semantics
.contact-section__fact-list {
margin: 0;
padding: 0;
.contact-section__fact {
display: flex;
flex-direction: column;
gap: 0.25rem;
margin-bottom: 1.25rem;
}
}
// ── Dark mode explicit overrides ─────────────────────────────────────────────
// CSS vars can silently fall back to light values in certain cascade scenarios.
// These scoped rules guarantee correct dark appearance regardless.
[data-theme='dark'] {
.contact-section {
// Card / form backgrounds
&__connect-card,
&__social-card,
&__info-card,
&__email-card,
&__form-card {
background: #042c53;
border-color: rgba(230, 241, 251, 0.12);
}
// Email button ochre fill, navy text
&__email-button {
background: #ef9f27;
color: #042c53;
&:hover {
background: #fac775;
color: #042c53;
}
}
// Form submit button
&__form-button {
background: #ef9f27;
color: #042c53;
&:hover:not(:disabled) {
background: #fac775;
}
}
// Social list icons (Globe, Linkedin) and links
&__social-icon {
color: #e6f1fb;
}
&__detail-item {
color: #e6f1fb;
}
&__detail-link {
color: #e6f1fb;
&:hover {
color: #ef9f27;
}
}
// Appointment hint block
&__appointment-hint {
background: rgba(12, 68, 124, 0.5);
border-color: rgba(230, 241, 251, 0.12);
}
&__appointment-icon,
&__appointment-text {
color: #e6f1fb;
}
&__appointment-link {
color: #e6f1fb;
&:hover {
color: #ef9f27;
}
}
// Email icon in header
&__email-icon {
color: #ef9f27;
background: rgba(239, 159, 39, 0.15);
}
// Titles within cards (compiled from $color-heading)
&__email-title,
&__connect-title,
&__social-title,
&__form-title {
color: #e6f1fb;
}
// Inputs
&__form-input,
&__form-textarea {
background: #021829;
color: #e6f1fb;
border-color: rgba(230, 241, 251, 0.2);
&::placeholder {
color: #b5d4f4;
}
}
}
}
// High contrast mode support
@media (prefers-contrast: high) {
.contact-section__social-button {
border: 2px solid currentColor !important;
&:focus {
outline: 4px solid currentColor !important;
}
}
}