diff --git a/src/assets/styles/Accordion.scss b/src/assets/styles/Accordion.scss new file mode 100644 index 0000000..06876e0 --- /dev/null +++ b/src/assets/styles/Accordion.scss @@ -0,0 +1,41 @@ +@use './variables.scss' as *; + +/* Accordion styling */ +.accordion-button { + background-color: $card-bg !important; + color: $text-light !important; + border-color: $card-border !important; + box-shadow: none !important; + padding: 1rem 1.25rem; + font-family: 'Cinzel', serif; +} + +.accordion-button:not(.collapsed) { + color: $accent-fire !important; +} + +.accordion-button:focus { + border-color: $accent-fire !important; + box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25) !important; +} + +.accordion-button::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ff6400'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") !important; +} + +.accordion-item { + background-color: transparent; + border: none; + margin-bottom: 1rem; +} + +.accordion-body { + background-color: $card-bg; + border: 1px solid $card-border; + border-top: none; + color: $text-ash; + padding: 1.25rem; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + border-bottom-left-radius: 0.375rem; + border-bottom-right-radius: 0.375rem; +} \ No newline at end of file diff --git a/src/assets/styles/Contact.module.scss b/src/assets/styles/Contact.module.scss new file mode 100644 index 0000000..0ce08ef --- /dev/null +++ b/src/assets/styles/Contact.module.scss @@ -0,0 +1,230 @@ +@use './variables' as *; +@use './card.scss' as card; + +@include card.card; + +/* Card styling */ +.contactCard { + position: relative; + border-left: 3px solid $accent-fire; + padding-left: 1.5rem; +} + +.contactIcon { + width: 50px; + height: 50px; + border-radius: 50%; + background-color: rgba(255, 100, 0, 0.1); + display: flex; + align-items: center; + justify-content: center; + color: $accent-fire; + font-size: 1.5rem; + margin-bottom: 1rem; +} + +.contactTitle { + font-size: 1.3rem; + color: $text-light; + margin-bottom: 1rem; +} + +.contactContent { + color: $text-ash; + line-height: 1.6; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +.contactLink { + color: $accent-fire; + text-decoration: none; + transition: all 0.3s ease; +} + +.contactLink:hover { + text-decoration: underline; + color: $accent-ember; +} + +/* Button styling */ +.btnPrimary { + background: linear-gradient(45deg, $accent-dragon, $accent-fire); + border: none; + padding: 0.75rem 2rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 1px; + box-shadow: 0 4px 15px rgba(139, 0, 0, 0.3); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.btnPrimary:hover { + transform: translateY(-3px); + box-shadow: 0 7px 25px rgba(139, 0, 0, 0.5); + background-color: $accent-fire; + background-image: none; +} + +.btnPrimary:focus { + box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.4); +} + +.btnPrimary::before { + content: ""; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); + transition: 0.6s; +} + +.btnPrimary:hover::before { + left: 100%; +} + +.btnPrimary:disabled { + background: linear-gradient(45deg, rgba(139, 0, 0, 0.5), rgba(255, 100, 0, 0.5)); + transform: none; +} + +/* Social links styling */ +.socialGrid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); + gap: 15px; + margin-top: 1.5rem; +} + +.socialItem { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 10px; + padding: 15px; + border-radius: 8px; + background-color: rgba(255, 255, 255, 0.05); + transition: all 0.3s ease; + text-decoration: none; +} + +.socialItem:hover { + background-color: rgba(255, 100, 0, 0.1); + transform: translateY(-5px); +} + +.socialIconLg { + font-size: 1.8rem; + color: $accent-fire; +} + +.socialName { + color: $text-ash; + font-size: 0.9rem; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +/* Map styling */ +.mapContainer { + position: relative; + overflow: hidden; + border-radius: 8px; + border: 1px solid $card-border; + margin-bottom: 2rem; +} + +.mapContainer::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 5px; + background: linear-gradient(to right, $accent-dragon, $accent-fire); + z-index: 1; +} + +.mapFrame { + width: 100%; + height: 400px; + border: none; + background-color: $card-bg; + filter: grayscale(90%) invert(92%) hue-rotate(180deg); +} + +/* Binary background effect */ +.binaryLine { + position: absolute; + font-family: 'Fira Code', monospace; + color: $accent-fire; + font-size: 0.8rem; + opacity: 0.15; + pointer-events: none; +} + +/* Ember effect */ +.emberParticle { + position: absolute; + width: 3px; + height: 3px; + background-color: $accent-fire; + border-radius: 50%; + opacity: 0.6; + pointer-events: none; + z-index: 2; + box-shadow: 0 0 5px $accent-fire; + animation: float 3s linear infinite; +} + +@keyframes float { + 0% { + transform: translateY(0) rotate(0deg); + opacity: 0.6; + } + + 100% { + transform: translateY(-100px) rotate(360deg); + opacity: 0; + } +} + +/* Table styling */ +.table { + color: $text-ash; + margin-bottom: 0; +} + +.table td { + padding: 0.5rem 0.25rem; + border-color: rgba(255, 255, 255, 0.05); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +@media (max-width: 768px) { + .schedule-container { + overflow-x: auto; + } + + .social-grid { + grid-template-columns: repeat(3, 1fr); + } + + .map-frame { + height: 300px; + } +} + +@media (max-width: 576px) { + .social-grid { + grid-template-columns: repeat(2, 1fr); + gap: 10px; + } + + .form-floating>label { + padding: 0.75rem 0.75rem; + } +} \ No newline at end of file diff --git a/src/assets/styles/FormControl.scss b/src/assets/styles/FormControl.scss new file mode 100644 index 0000000..4595d48 --- /dev/null +++ b/src/assets/styles/FormControl.scss @@ -0,0 +1,95 @@ +@use './variables.scss' as *; + +/* Form styling */ +.form-control { + background-color: rgba(255, 255, 255, 0.05); + border: 1px solid var(--card-border); + color: var(--text-light); + padding: 0.75rem 0.9375rem; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +.form-control:focus { + background-color: rgba(255, 255, 255, 0.08); + border-color: var(--accent-fire); + box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25); + color: var(--text-light); +} + +.form-control::placeholder { + color: rgba(255, 255, 255, 0.3); +} + +textarea.form-control { + min-height: 120px; +} + +.form-label { + color: var(--text-ash); + font-weight: 600; + margin-bottom: 0.5rem; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +.form-text { + color: rgba(255, 255, 255, 0.5); +} + +.form-select { + background-color: rgba(255, 255, 255, 0.05); + border: 1px solid var(--card-border); + color: var(--text-light); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ff6400' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +.form-select:focus { + background-color: rgba(255, 255, 255, 0.08); + border-color: var(--accent-fire); + box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25); + color: var(--text-light); +} + +.form-select option { + background-color: var(--card-bg); + color: var(--text-light); +} + +/* Alert styling */ +.alert-success { + background-color: rgba(25, 135, 84, 0.1); + border-color: rgba(25, 135, 84, 0.3); + color: #75b798; +} + +.alert-danger { + background-color: rgba(220, 53, 69, 0.1); + border-color: rgba(220, 53, 69, 0.3); + color: #ea868f; +} + +/* Form validation styling */ +.was-validated .form-control:invalid, +.form-control.is-invalid { + border-color: #dc3545; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.was-validated .form-control:valid, +.form-control.is-valid { + border-color: #198754; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} + +.invalid-feedback { + color: #dc3545; + font-size: 0.875em; + margin-top: 0.25rem; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} \ No newline at end of file diff --git a/src/assets/styles/_variables.scss b/src/assets/styles/_variables.scss index b147616..b2d30d2 100644 --- a/src/assets/styles/_variables.scss +++ b/src/assets/styles/_variables.scss @@ -9,6 +9,7 @@ $text-ash: #aaaaaa; $card-bg: #141414; $card-border: #2a2a2a; $code-bg: #1e1e1e; +$font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; // Effects $glow-effect: 0 0 10px $accent-fire, 0 0 20px rgba(255, 100, 0, 0.4); diff --git a/src/assets/styles/card.scss b/src/assets/styles/card.scss new file mode 100644 index 0000000..999ad18 --- /dev/null +++ b/src/assets/styles/card.scss @@ -0,0 +1,35 @@ +@use './variables.scss' as *; + +/* Card styling */ +@mixin card { + .card { + background-color: $card-bg; + border: 1px solid $card-border; + border-radius: 8px; + transition: all 0.3s ease; + overflow: hidden; + } + + .card:hover { + transform: translateY(-7px); + border-color: rgba(255, 100, 0, 0.3); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); + } + + .card::before { + content: ""; + position: absolute; + width: 100%; + height: 5px; + top: 0; + left: 0; + background: linear-gradient(to right, $accent-dragon, $accent-fire); + z-index: 1; + } + + @media (max-width: 576px) { + .card-body { + padding: 1.25rem; + } + } +} \ No newline at end of file diff --git a/src/components/ContactForm.tsx b/src/components/ContactForm.tsx index 792eb1c..0209f3e 100644 --- a/src/components/ContactForm.tsx +++ b/src/components/ContactForm.tsx @@ -1,4 +1,6 @@ import { useState, type FormEvent } from 'react'; +import '@styles/FormControl.scss' +import styles from '@styles/Contact.module.scss' export const ContactForm = () => { const [formData, setFormData] = useState({ @@ -47,11 +49,11 @@ export const ContactForm = () => { }; return ( -
-
+
+

Send a Message to the Forge

-
+
{/* Success message */} {showSuccess && (
@@ -176,7 +178,7 @@ export const ContactForm = () => {
- -
-
- Project timelines vary based on complexity and scope. Small projects typically take 2-4 weeks, medium-sized projects 1-2 months, and larger enterprise solutions 3-6 months. I provide detailed timeline estimates during the initial consultation, and maintain transparent communication about progress throughout the development cycle. + { + data.questionsAndAnswers.map((item, index) => ( +
+

+ +

+
+
+ {item.answer} +
+
-
-
- - {/* FAQ Item 2 */} -
-

- -

-
-
- My collaboration process consists of five phases: initial consultation, requirements gathering, design and planning, implementation, and testing/deployment. I use agile methodologies with regular check-ins to ensure your vision is being realized. Communication is maintained through your preferred channels (email, Slack, etc.), and you'll have access to development milestones through shared repositories and project management tools. -
-
-
- - {/* FAQ Item 3 */} -
-

- -

-
-
- I typically work with a milestone-based payment structure: 30% upfront to begin work, 30% at the midpoint after key deliverables are approved, and 40% upon project completion. For longer projects, we can establish additional milestones. I accept bank transfers, PayPal, and cryptocurrency payments. All payment terms are clearly outlined in the project contract before work begins. -
-
-
+ )) + }
- - + + {/* Map Section */} -
+ < section className="py-5" >
@@ -196,19 +142,19 @@ export const Contact = () => {
-
-
-
+ ); }; \ No newline at end of file diff --git a/src/untils/ContactProps.ts b/src/untils/ContactProps.ts new file mode 100644 index 0000000..378d549 --- /dev/null +++ b/src/untils/ContactProps.ts @@ -0,0 +1,19 @@ +export interface ContactProps { + email: string; + businessEmail: string; + socialLinks: SocialLink[]; + questionsAndAnswers: QuestionAndAnswer[]; + MapIframeUrl: string; + phone: string; +} + +export interface SocialLink { + platform: string; + url: string; + icon: string; +} + +export interface QuestionAndAnswer { + question: string; + answer: string; +} \ No newline at end of file