some fixes

This commit is contained in:
2025-10-22 21:22:44 +09:00
parent 46fad7ecc2
commit 6ff35e26f4
514 changed files with 156165 additions and 0 deletions

View File

@@ -0,0 +1,325 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Hero Section */
.hero-section {
min-height: 100vh !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
color: white !important;
text-align: center !important;
padding: 2rem !important;
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,325 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Hero Section */
.hero-section {
min-height: 100vh !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
color: white !important;
text-align: center !important;
padding: 2rem !important;
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,590 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Base CSS - Принудительные стили для правильного отображения */
/* Reset и базовые стили */
* {
box-sizing: border-box !important;
}
html, body {
margin: 0 !important;
padding: 0 !important;
font-family: 'Inter', system-ui, -apple-system, sans-serif !important;
line-height: 1.6 !important;
color: #333 !important;
scroll-behavior: smooth !important;
}
body {
padding-top: 80px !important; /* Отступ для фиксированной навигации */
}
/* Навигация */
nav, .navigation {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
height: 80px !important;
}
.navbar, .nav-container {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
padding: 1rem 2rem !important;
max-width: 1200px !important;
margin: 0 auto !important;
height: 100% !important;
}
.logo, .brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #1d4ed8 !important;
text-decoration: none !important;
}
.nav-links, .menu {
display: flex !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2rem !important;
}
.nav-links a, .menu a {
color: #374151 !important;
text-decoration: none !important;
font-weight: 500 !important;
transition: color 0.3s ease !important;
padding: 0.5rem 0 !important;
}
.nav-links a:hover, .menu a:hover {
color: #1d4ed8 !important;
}
/* Hero секция */
.hero-section {
min-height: 100vh !important;
background: linear-gradient(135deg, #1e3a8a 0%, #7c3aed 50%, #3730a3 100%) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
text-align: center !important;
color: white !important;
position: relative !important;
overflow: hidden !important;
margin-top: -80px !important; /* Компенсация отступа */
padding-top: 80px !important;
}
.hero-section h1 {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1.5rem !important;
line-height: 1.2 !important;
}
.hero-section p {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
opacity: 0.9 !important;
}
/* Кнопки */
.btn-primary, .btn {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 1rem 2rem !important;
background: linear-gradient(45deg, #3b82f6, #8b5cf6) !important;
color: white !important;
text-decoration: none !important;
border-radius: 50px !important;
font-weight: 600 !important;
transition: all 0.3s ease !important;
border: none !important;
cursor: pointer !important;
font-size: 1rem !important;
}
.btn-primary:hover, .btn:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 30px rgba(59, 130, 246, 0.3) !important;
}
/* Карточки */
.card-hover, .card {
transition: all 0.3s ease !important;
border-radius: 1rem !important;
overflow: hidden !important;
background: white !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
}
.card-hover:hover, .card:hover {
transform: translateY(-8px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Секции */
section {
padding: 5rem 1rem !important;
}
.container, .max-w-7xl {
max-width: 1200px !important;
margin: 0 auto !important;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
/* Грид системы */
.grid {
display: grid !important;
}
.grid-cols-1 {
grid-template-columns: 1fr !important;
}
.grid-cols-2 {
grid-template-columns: repeat(2, 1fr) !important;
}
.grid-cols-3 {
grid-template-columns: repeat(3, 1fr) !important;
}
.grid-cols-4 {
grid-template-columns: repeat(4, 1fr) !important;
}
.gap-8 {
gap: 2rem !important;
}
/* Заголовки */
h1, h2, h3, h4, h5, h6 {
color: #1f2937 !important;
font-weight: 600 !important;
}
h1 {
font-size: 3rem !important;
}
h2 {
font-size: 2.5rem !important;
}
h3 {
font-size: 1.75rem !important;
}
/* Footer */
footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 1rem 1rem !important;
}
/* Отзывчивость */
@media (max-width: 768px) {
.nav-links, .menu {
display: none !important;
}
body {
padding-top: 60px !important;
}
nav, .navigation {
height: 60px !important;
}
.hero-section {
margin-top: -60px !important;
padding-top: 60px !important;
}
section {
padding: 3rem 1rem !important;
}
.hero-section h1 {
font-size: 2.5rem !important;
}
.grid-cols-2, .grid-cols-3, .grid-cols-4 {
grid-template-columns: 1fr !important;
}
}
/* Дополнительные утилитарные классы */
.text-center {
text-align: center !important;
}
.text-white {
color: white !important;
}
.bg-white {
background-color: white !important;
}
.rounded-lg {
border-radius: 0.5rem !important;
}
.rounded-2xl {
border-radius: 1rem !important;
}
.shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
.mb-4 {
margin-bottom: 1rem !important;
}
.mb-8 {
margin-bottom: 2rem !important;
}
.p-8 {
padding: 2rem !important;
}
.flex {
display: flex !important;
}
.items-center {
align-items: center !important;
}
.justify-center {
justify-content: center !important;
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,591 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Base CSS - Принудительные стили для правильного отображения */
/* Reset и базовые стили */
* {
box-sizing: border-box !important;
}
html, body {
margin: 0 !important;
padding: 0 !important;
font-family: 'Inter', system-ui, -apple-system, sans-serif !important;
line-height: 1.6 !important;
color: #333 !important;
scroll-behavior: smooth !important;
}
body {
padding-top: 80px !important; /* Отступ для фиксированной навигации */
}
/* Навигация */
nav, .navigation {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
-webkit-backdrop-filter: blur(10px) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
height: 80px !important;
}
.navbar, .nav-container {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
padding: 1rem 2rem !important;
max-width: 1200px !important;
margin: 0 auto !important;
height: 100% !important;
}
.logo, .brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #1d4ed8 !important;
text-decoration: none !important;
}
.nav-links, .menu {
display: flex !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2rem !important;
}
.nav-links a, .menu a {
color: #374151 !important;
text-decoration: none !important;
font-weight: 500 !important;
transition: color 0.3s ease !important;
padding: 0.5rem 0 !important;
}
.nav-links a:hover, .menu a:hover {
color: #1d4ed8 !important;
}
/* Hero секция */
.hero-section {
min-height: 100vh !important;
background: linear-gradient(135deg, #1e3a8a 0%, #7c3aed 50%, #3730a3 100%) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
text-align: center !important;
color: white !important;
position: relative !important;
overflow: hidden !important;
margin-top: -80px !important; /* Компенсация отступа */
padding-top: 80px !important;
}
.hero-section h1 {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1.5rem !important;
line-height: 1.2 !important;
}
.hero-section p {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
opacity: 0.9 !important;
}
/* Кнопки */
.btn-primary, .btn {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 1rem 2rem !important;
background: linear-gradient(45deg, #3b82f6, #8b5cf6) !important;
color: white !important;
text-decoration: none !important;
border-radius: 50px !important;
font-weight: 600 !important;
transition: all 0.3s ease !important;
border: none !important;
cursor: pointer !important;
font-size: 1rem !important;
}
.btn-primary:hover, .btn:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 30px rgba(59, 130, 246, 0.3) !important;
}
/* Карточки */
.card-hover, .card {
transition: all 0.3s ease !important;
border-radius: 1rem !important;
overflow: hidden !important;
background: white !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
}
.card-hover:hover, .card:hover {
transform: translateY(-8px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Секции */
section {
padding: 5rem 1rem !important;
}
.container, .max-w-7xl {
max-width: 1200px !important;
margin: 0 auto !important;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
/* Грид системы */
.grid {
display: grid !important;
}
.grid-cols-1 {
grid-template-columns: 1fr !important;
}
.grid-cols-2 {
grid-template-columns: repeat(2, 1fr) !important;
}
.grid-cols-3 {
grid-template-columns: repeat(3, 1fr) !important;
}
.grid-cols-4 {
grid-template-columns: repeat(4, 1fr) !important;
}
.gap-8 {
gap: 2rem !important;
}
/* Заголовки */
h1, h2, h3, h4, h5, h6 {
color: #1f2937 !important;
font-weight: 600 !important;
}
h1 {
font-size: 3rem !important;
}
h2 {
font-size: 2.5rem !important;
}
h3 {
font-size: 1.75rem !important;
}
/* Footer */
footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 1rem 1rem !important;
}
/* Отзывчивость */
@media (max-width: 768px) {
.nav-links, .menu {
display: none !important;
}
body {
padding-top: 60px !important;
}
nav, .navigation {
height: 60px !important;
}
.hero-section {
margin-top: -60px !important;
padding-top: 60px !important;
}
section {
padding: 3rem 1rem !important;
}
.hero-section h1 {
font-size: 2.5rem !important;
}
.grid-cols-2, .grid-cols-3, .grid-cols-4 {
grid-template-columns: 1fr !important;
}
}
/* Дополнительные утилитарные классы */
.text-center {
text-align: center !important;
}
.text-white {
color: white !important;
}
.bg-white {
background-color: white !important;
}
.rounded-lg {
border-radius: 0.5rem !important;
}
.rounded-2xl {
border-radius: 1rem !important;
}
.shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
.mb-4 {
margin-bottom: 1rem !important;
}
.mb-8 {
margin-bottom: 2rem !important;
}
.p-8 {
padding: 2rem !important;
}
.flex {
display: flex !important;
}
.items-center {
align-items: center !important;
}
.justify-center {
justify-content: center !important;
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,591 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Base CSS - Принудительные стили для правильного отображения */
/* Reset и базовые стили */
* {
box-sizing: border-box !important;
}
html, body {
margin: 0 !important;
padding: 0 !important;
font-family: 'Inter', system-ui, -apple-system, sans-serif !important;
line-height: 1.6 !important;
color: #333 !important;
scroll-behavior: smooth !important;
}
body {
padding-top: 80px !important; /* Отступ для фиксированной навигации */
}
/* Навигация */
nav, .navigation {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
-webkit-backdrop-filter: blur(10px) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
height: 80px !important;
}
.navbar, .nav-container {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
padding: 1rem 2rem !important;
max-width: 1200px !important;
margin: 0 auto !important;
height: 100% !important;
}
.logo, .brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #1d4ed8 !important;
text-decoration: none !important;
}
.nav-links, .menu {
display: flex !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2rem !important;
}
.nav-links a, .menu a {
color: #374151 !important;
text-decoration: none !important;
font-weight: 500 !important;
transition: color 0.3s ease !important;
padding: 0.5rem 0 !important;
}
.nav-links a:hover, .menu a:hover {
color: #1d4ed8 !important;
}
/* Hero секция */
.hero-section {
min-height: 100vh !important;
background: linear-gradient(135deg, #1e3a8a 0%, #7c3aed 50%, #3730a3 100%) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
text-align: center !important;
color: white !important;
position: relative !important;
overflow: hidden !important;
margin-top: -80px !important; /* Компенсация отступа */
padding-top: 80px !important;
}
.hero-section h1 {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1.5rem !important;
line-height: 1.2 !important;
}
.hero-section p {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
opacity: 0.9 !important;
}
/* Кнопки */
.btn-primary, .btn {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 1rem 2rem !important;
background: linear-gradient(45deg, #3b82f6, #8b5cf6) !important;
color: white !important;
text-decoration: none !important;
border-radius: 50px !important;
font-weight: 600 !important;
transition: all 0.3s ease !important;
border: none !important;
cursor: pointer !important;
font-size: 1rem !important;
}
.btn-primary:hover, .btn:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 30px rgba(59, 130, 246, 0.3) !important;
}
/* Карточки */
.card-hover, .card {
transition: all 0.3s ease !important;
border-radius: 1rem !important;
overflow: hidden !important;
background: white !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
}
.card-hover:hover, .card:hover {
transform: translateY(-8px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Секции */
section {
padding: 5rem 1rem !important;
}
.container, .max-w-7xl {
max-width: 1200px !important;
margin: 0 auto !important;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
/* Грид системы */
.grid {
display: grid !important;
}
.grid-cols-1 {
grid-template-columns: 1fr !important;
}
.grid-cols-2 {
grid-template-columns: repeat(2, 1fr) !important;
}
.grid-cols-3 {
grid-template-columns: repeat(3, 1fr) !important;
}
.grid-cols-4 {
grid-template-columns: repeat(4, 1fr) !important;
}
.gap-8 {
gap: 2rem !important;
}
/* Заголовки */
h1, h2, h3, h4, h5, h6 {
color: #1f2937 !important;
font-weight: 600 !important;
}
h1 {
font-size: 3rem !important;
}
h2 {
font-size: 2.5rem !important;
}
h3 {
font-size: 1.75rem !important;
}
/* Footer */
footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 1rem 1rem !important;
}
/* Отзывчивость */
@media (max-width: 768px) {
.nav-links, .menu {
display: none !important;
}
body {
padding-top: 60px !important;
}
nav, .navigation {
height: 60px !important;
}
.hero-section {
margin-top: -60px !important;
padding-top: 60px !important;
}
section {
padding: 3rem 1rem !important;
}
.hero-section h1 {
font-size: 2.5rem !important;
}
.grid-cols-2, .grid-cols-3, .grid-cols-4 {
grid-template-columns: 1fr !important;
}
}
/* Дополнительные утилитарные классы */
.text-center {
text-align: center !important;
}
.text-white {
color: white !important;
}
.bg-white {
background-color: white !important;
}
.rounded-lg {
border-radius: 0.5rem !important;
}
.rounded-2xl {
border-radius: 1rem !important;
}
.shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
.mb-4 {
margin-bottom: 1rem !important;
}
.mb-8 {
margin-bottom: 2rem !important;
}
.p-8 {
padding: 2rem !important;
}
.flex {
display: flex !important;
}
.items-center {
align-items: center !important;
}
.justify-center {
justify-content: center !important;
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,686 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Base CSS - Исправленные стили для главной страницы */
/* Reset и базовые стили */
* {
box-sizing: border-box !important;
margin: 0 !important;
padding: 0 !important;
}
html {
font-size: 16px !important;
scroll-behavior: smooth !important;
}
body {
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
line-height: 1.6 !important;
color: #1f2937 !important;
background-color: #ffffff !important;
margin: 0 !important;
padding: 0 !important;
padding-top: 80px !important; /* Отступ для навигации */
}
/* Навигация - исправленная */
nav, .navigation {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
-webkit-backdrop-filter: blur(20px) !important;
backdrop-filter: blur(20px) !important;
border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;
height: 80px !important;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1) !important;
}
.navbar, .nav-container {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
padding: 0 2rem !important;
max-width: 1200px !important;
margin: 0 auto !important;
height: 100% !important;
}
.logo, .brand {
font-size: 1.75rem !important;
font-weight: 800 !important;
color: #1d4ed8 !important;
text-decoration: none !important;
letter-spacing: -0.025em !important;
}
.nav-links, .menu {
display: flex !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2.5rem !important;
}
.nav-links li, .menu li {
margin: 0 !important;
padding: 0 !important;
}
.nav-links a, .menu a {
color: #374151 !important;
text-decoration: none !important;
font-weight: 500 !important;
font-size: 0.95rem !important;
transition: all 0.3s ease !important;
padding: 0.75rem 0 !important;
position: relative !important;
}
.nav-links a:hover, .menu a:hover {
color: #1d4ed8 !important;
transform: translateY(-1px) !important;
}
.nav-links a::after, .menu a::after {
content: '' !important;
position: absolute !important;
bottom: 0.5rem !important;
left: 0 !important;
width: 0 !important;
height: 2px !important;
background: linear-gradient(45deg, #1d4ed8, #8b5cf6) !important;
transition: width 0.3s ease !important;
}
.nav-links a:hover::after, .menu a:hover::after {
width: 100% !important;
}
/* Hero секция - исправленная */
.hero-section {
min-height: 100vh !important;
background: linear-gradient(135deg, #0f172a 0%, #1e1b4b 25%, #312e81 50%, #7c3aed 75%, #3730a3 100%) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
text-align: center !important;
color: white !important;
position: relative !important;
overflow: hidden !important;
margin-top: -80px !important;
padding-top: 80px !important;
}
.hero-section::before {
content: '' !important;
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
background: radial-gradient(circle at 30% 40%, rgba(59, 130, 246, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.3) 0%, transparent 50%),
radial-gradient(circle at 40% 80%, rgba(16, 185, 129, 0.2) 0%, transparent 50%) !important;
z-index: 1 !important;
}
.hero-section > div {
position: relative !important;
z-index: 2 !important;
}
.hero-section h1 {
font-size: 4rem !important;
font-weight: 800 !important;
margin-bottom: 1.5rem !important;
line-height: 1.1 !important;
letter-spacing: -0.025em !important;
}
.hero-section p {
font-size: 1.35rem !important;
margin-bottom: 2.5rem !important;
opacity: 0.9 !important;
max-width: 600px !important;
margin-left: auto !important;
margin-right: auto !important;
}
/* Кнопки - улучшенные */
.btn-primary, .btn {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 1.25rem 2.5rem !important;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%) !important;
color: white !important;
text-decoration: none !important;
border-radius: 50px !important;
font-weight: 700 !important;
font-size: 1.1rem !important;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
border: none !important;
cursor: pointer !important;
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3) !important;
position: relative !important;
overflow: hidden !important;
}
.btn-primary:hover, .btn:hover {
transform: translateY(-3px) scale(1.05) !important;
box-shadow: 0 15px 35px rgba(59, 130, 246, 0.4) !important;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%) !important;
}
.btn-primary::before, .btn::before {
content: '' !important;
position: absolute !important;
top: 0 !important;
left: -100% !important;
width: 100% !important;
height: 100% !important;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent) !important;
transition: left 0.6s !important;
}
.btn-primary:hover::before, .btn:hover::before {
left: 100% !important;
}
/* Карточки - улучшенные */
.card-hover, .card {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
border-radius: 1.5rem !important;
overflow: hidden !important;
background: white !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05) !important;
border: 1px solid rgba(0, 0, 0, 0.05) !important;
}
.card-hover:hover, .card:hover {
transform: translateY(-12px) scale(1.02) !important;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15) !important;
border-color: rgba(59, 130, 246, 0.2) !important;
}
/* Секции */
section {
padding: 6rem 1rem !important;
position: relative !important;
}
.container, .max-w-7xl {
max-width: 1200px !important;
margin: 0 auto !important;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
/* Заголовки */
h1, h2, h3, h4, h5, h6 {
color: #1f2937 !important;
font-weight: 700 !important;
line-height: 1.2 !important;
}
h2 {
font-size: 2.75rem !important;
margin-bottom: 1rem !important;
}
h3 {
font-size: 1.5rem !important;
margin-bottom: 0.75rem !important;
}
/* Параграфы и текст */
p {
color: #6b7280 !important;
line-height: 1.7 !important;
margin-bottom: 1rem !important;
}
/* Утилитарные классы Tailwind - принудительные */
.text-center {
text-align: center !important;
}
.text-white {
color: white !important;
}
.bg-white {
background-color: white !important;
}
.bg-gray-50 {
background-color: #f9fafb !important;
}
.rounded-lg {
border-radius: 0.5rem !important;
}
.rounded-2xl {
border-radius: 1rem !important;
}
.shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
.mb-4 {
margin-bottom: 1rem !important;
}
.mb-8 {
margin-bottom: 2rem !important;
}
.p-8 {
padding: 2rem !important;
}
.flex {
display: flex !important;
}
.grid {
display: grid !important;
}
.items-center {
align-items: center !important;
}
.justify-center {
justify-content: center !important;
}
/* Грид системы */
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
.grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
}
.grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}
.gap-8 {
gap: 2rem !important;
}
/* Отзывчивость - улучшенная */
@media (max-width: 1024px) {
.grid-cols-4 {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
.hero-section h1 {
font-size: 3.5rem !important;
}
}
@media (max-width: 768px) {
.nav-links, .menu {
display: none !important;
}
body {
padding-top: 60px !important;
}
nav, .navigation {
height: 60px !important;
}
.hero-section {
margin-top: -60px !important;
padding-top: 60px !important;
}
section {
padding: 4rem 1rem !important;
}
.hero-section h1 {
font-size: 2.75rem !important;
}
.hero-section p {
font-size: 1.1rem !important;
}
.grid-cols-2, .grid-cols-3, .grid-cols-4 {
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
}
.btn-primary, .btn {
padding: 1rem 2rem !important;
font-size: 1rem !important;
}
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,686 @@
/* SmartSolTech - Base Styles for Elements */
/* Ensure proper styling without Tailwind conflicts */
.navbar {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
border-bottom: 1px solid #e5e7eb !important;
padding: 1rem 0 !important;
}
.navbar-brand {
font-size: 1.5rem !important;
font-weight: 700 !important;
color: #3B82F6 !important;
text-decoration: none !important;
}
.navbar-nav {
display: flex !important;
align-items: center !important;
gap: 2rem !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
}
.nav-link {
color: #6b7280 !important;
text-decoration: none !important;
font-weight: 500 !important;
padding: 0.5rem 1rem !important;
border-radius: 0.5rem !important;
transition: all 0.3s ease !important;
}
.nav-link:hover,
.nav-link.active {
color: #3B82F6 !important;
background-color: #eff6ff !important;
}
/* Base CSS - Исправленные стили для главной страницы */
/* Reset и базовые стили */
* {
box-sizing: border-box !important;
margin: 0 !important;
padding: 0 !important;
}
html {
font-size: 16px !important;
scroll-behavior: smooth !important;
}
body {
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
line-height: 1.6 !important;
color: #1f2937 !important;
background-color: #ffffff !important;
margin: 0 !important;
padding: 0 !important;
padding-top: 80px !important; /* Отступ для навигации */
}
/* Навигация - исправленная */
nav, .navigation {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 1000 !important;
background: rgba(255, 255, 255, 0.95) !important;
-webkit-backdrop-filter: blur(20px) !important;
backdrop-filter: blur(20px) !important;
border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important;
height: 80px !important;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1) !important;
}
.navbar, .nav-container {
display: flex !important;
justify-content: space-between !important;
align-items: center !important;
padding: 0 2rem !important;
max-width: 1200px !important;
margin: 0 auto !important;
height: 100% !important;
}
.logo, .brand {
font-size: 1.75rem !important;
font-weight: 800 !important;
color: #1d4ed8 !important;
text-decoration: none !important;
letter-spacing: -0.025em !important;
}
.nav-links, .menu {
display: flex !important;
list-style: none !important;
margin: 0 !important;
padding: 0 !important;
gap: 2.5rem !important;
}
.nav-links li, .menu li {
margin: 0 !important;
padding: 0 !important;
}
.nav-links a, .menu a {
color: #374151 !important;
text-decoration: none !important;
font-weight: 500 !important;
font-size: 0.95rem !important;
transition: all 0.3s ease !important;
padding: 0.75rem 0 !important;
position: relative !important;
}
.nav-links a:hover, .menu a:hover {
color: #1d4ed8 !important;
transform: translateY(-1px) !important;
}
.nav-links a::after, .menu a::after {
content: '' !important;
position: absolute !important;
bottom: 0.5rem !important;
left: 0 !important;
width: 0 !important;
height: 2px !important;
background: linear-gradient(45deg, #1d4ed8, #8b5cf6) !important;
transition: width 0.3s ease !important;
}
.nav-links a:hover::after, .menu a:hover::after {
width: 100% !important;
}
/* Hero секция - исправленная */
.hero-section {
min-height: 100vh !important;
background: linear-gradient(135deg, #0f172a 0%, #1e1b4b 25%, #312e81 50%, #7c3aed 75%, #3730a3 100%) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
text-align: center !important;
color: white !important;
position: relative !important;
overflow: hidden !important;
margin-top: -80px !important;
padding-top: 80px !important;
}
.hero-section::before {
content: '' !important;
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
background: radial-gradient(circle at 30% 40%, rgba(59, 130, 246, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(139, 92, 246, 0.3) 0%, transparent 50%),
radial-gradient(circle at 40% 80%, rgba(16, 185, 129, 0.2) 0%, transparent 50%) !important;
z-index: 1 !important;
}
.hero-section > div {
position: relative !important;
z-index: 2 !important;
}
.hero-section h1 {
font-size: 4rem !important;
font-weight: 800 !important;
margin-bottom: 1.5rem !important;
line-height: 1.1 !important;
letter-spacing: -0.025em !important;
}
.hero-section p {
font-size: 1.35rem !important;
margin-bottom: 2.5rem !important;
opacity: 0.9 !important;
max-width: 600px !important;
margin-left: auto !important;
margin-right: auto !important;
}
/* Кнопки - улучшенные */
.btn-primary, .btn {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
padding: 1.25rem 2.5rem !important;
background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%) !important;
color: white !important;
text-decoration: none !important;
border-radius: 50px !important;
font-weight: 700 !important;
font-size: 1.1rem !important;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
border: none !important;
cursor: pointer !important;
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.3) !important;
position: relative !important;
overflow: hidden !important;
}
.btn-primary:hover, .btn:hover {
transform: translateY(-3px) scale(1.05) !important;
box-shadow: 0 15px 35px rgba(59, 130, 246, 0.4) !important;
background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%) !important;
}
.btn-primary::before, .btn::before {
content: '' !important;
position: absolute !important;
top: 0 !important;
left: -100% !important;
width: 100% !important;
height: 100% !important;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent) !important;
transition: left 0.6s !important;
}
.btn-primary:hover::before, .btn:hover::before {
left: 100% !important;
}
/* Карточки - улучшенные */
.card-hover, .card {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
border-radius: 1.5rem !important;
overflow: hidden !important;
background: white !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05) !important;
border: 1px solid rgba(0, 0, 0, 0.05) !important;
}
.card-hover:hover, .card:hover {
transform: translateY(-12px) scale(1.02) !important;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15) !important;
border-color: rgba(59, 130, 246, 0.2) !important;
}
/* Секции */
section {
padding: 6rem 1rem !important;
position: relative !important;
}
.container, .max-w-7xl {
max-width: 1200px !important;
margin: 0 auto !important;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
/* Заголовки */
h1, h2, h3, h4, h5, h6 {
color: #1f2937 !important;
font-weight: 700 !important;
line-height: 1.2 !important;
}
h2 {
font-size: 2.75rem !important;
margin-bottom: 1rem !important;
}
h3 {
font-size: 1.5rem !important;
margin-bottom: 0.75rem !important;
}
/* Параграфы и текст */
p {
color: #6b7280 !important;
line-height: 1.7 !important;
margin-bottom: 1rem !important;
}
/* Утилитарные классы Tailwind - принудительные */
.text-center {
text-align: center !important;
}
.text-white {
color: white !important;
}
.bg-white {
background-color: white !important;
}
.bg-gray-50 {
background-color: #f9fafb !important;
}
.rounded-lg {
border-radius: 0.5rem !important;
}
.rounded-2xl {
border-radius: 1rem !important;
}
.shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
.mb-4 {
margin-bottom: 1rem !important;
}
.mb-8 {
margin-bottom: 2rem !important;
}
.p-8 {
padding: 2rem !important;
}
.flex {
display: flex !important;
}
.grid {
display: grid !important;
}
.items-center {
align-items: center !important;
}
.justify-center {
justify-content: center !important;
}
/* Грид системы */
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
.grid-cols-3 {
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
}
.grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}
.gap-8 {
gap: 2rem !important;
}
/* Отзывчивость - улучшенная */
@media (max-width: 1024px) {
.grid-cols-4 {
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
.hero-section h1 {
font-size: 3.5rem !important;
}
}
@media (max-width: 768px) {
.nav-links, .menu {
display: none !important;
}
body {
padding-top: 60px !important;
}
nav, .navigation {
height: 60px !important;
}
.hero-section {
margin-top: -60px !important;
padding-top: 60px !important;
}
section {
padding: 4rem 1rem !important;
}
.hero-section h1 {
font-size: 2.75rem !important;
}
.hero-section p {
font-size: 1.1rem !important;
}
.grid-cols-2, .grid-cols-3, .grid-cols-4 {
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
}
.btn-primary, .btn {
padding: 1rem 2rem !important;
font-size: 1rem !important;
}
}
.hero-title {
font-size: 3.5rem !important;
font-weight: 700 !important;
margin-bottom: 1rem !important;
line-height: 1.2 !important;
}
.hero-subtitle {
font-size: 1.25rem !important;
margin-bottom: 2rem !important;
color: rgba(255, 255, 255, 0.9) !important;
}
/* Buttons */
.btn {
display: inline-block !important;
padding: 0.75rem 1.5rem !important;
border-radius: 0.5rem !important;
text-decoration: none !important;
font-weight: 600 !important;
text-align: center !important;
border: none !important;
cursor: pointer !important;
transition: all 0.3s ease !important;
font-size: 1rem !important;
}
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8) !important;
color: white !important;
}
.btn-primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3) !important;
}
.btn-secondary {
background: transparent !important;
color: white !important;
border: 2px solid white !important;
}
.btn-secondary:hover {
background: white !important;
color: #3B82F6 !important;
}
/* Cards */
.card {
background: white !important;
border-radius: 1rem !important;
padding: 2rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.card:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
/* Sections */
.section {
padding: 4rem 2rem !important;
}
.section-title {
font-size: 2.5rem !important;
font-weight: 700 !important;
text-align: center !important;
margin-bottom: 1rem !important;
color: #1f2937 !important;
}
.section-description {
font-size: 1.125rem !important;
text-align: center !important;
color: #6b7280 !important;
max-width: 600px !important;
margin: 0 auto 3rem !important;
}
/* Container */
.container {
max-width: 1200px !important;
margin: 0 auto !important;
padding: 0 1rem !important;
}
/* Grid Layouts */
.grid-2 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) !important;
gap: 2rem !important;
}
.grid-3 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
gap: 2rem !important;
}
.grid-4 {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 1.5rem !important;
}
/* Language Selector */
.language-selector {
display: flex !important;
align-items: center !important;
gap: 0.5rem !important;
}
.language-selector a {
color: #6b7280 !important;
text-decoration: none !important;
padding: 0.25rem 0.5rem !important;
border-radius: 0.25rem !important;
font-size: 0.875rem !important;
}
.language-selector a:hover {
color: #3B82F6 !important;
background-color: #f3f4f6 !important;
}
/* Mobile Menu */
.mobile-menu-button {
display: none !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
color: #6b7280 !important;
cursor: pointer !important;
}
/* Mobile Styles */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem !important;
}
.mobile-menu-button {
display: block !important;
}
.navbar-nav {
display: none !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
right: 0 !important;
background: white !important;
flex-direction: column !important;
padding: 1rem !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
.navbar-nav.show {
display: flex !important;
}
.section {
padding: 2rem 1rem !important;
}
.section-title {
font-size: 2rem !important;
}
}
/* Footer */
.footer {
background: #1f2937 !important;
color: white !important;
padding: 3rem 2rem 1rem !important;
text-align: center !important;
}
.footer p {
color: #d1d5db !important;
}
/* Service Icons */
.service-icon {
width: 80px !important;
height: 80px !important;
background: linear-gradient(135deg, #3B82F6, #8B5CF6) !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 2rem !important;
color: white !important;
margin: 0 auto 1rem !important;
}
/* Portfolio Items */
.portfolio-item {
background: white !important;
border-radius: 1rem !important;
overflow: hidden !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05) !important;
transition: all 0.3s ease !important;
}
.portfolio-item:hover {
transform: translateY(-4px) !important;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1) !important;
}
.portfolio-image {
width: 100% !important;
height: 200px !important;
object-fit: cover !important;
display: block !important;
}
.portfolio-content {
padding: 1.5rem !important;
}
.portfolio-title {
font-size: 1.25rem !important;
font-weight: 600 !important;
margin-bottom: 0.5rem !important;
color: #1f2937 !important;
}
.portfolio-description {
color: #6b7280 !important;
margin-bottom: 1rem !important;
}
/* Form Styles */
.form-group {
margin-bottom: 1.5rem !important;
}
.form-label {
display: block !important;
font-weight: 500 !important;
margin-bottom: 0.5rem !important;
color: #374151 !important;
}
.form-input,
.form-textarea,
.form-select {
width: 100% !important;
padding: 0.75rem !important;
border: 2px solid #e5e7eb !important;
border-radius: 0.5rem !important;
font-size: 1rem !important;
transition: all 0.3s ease !important;
}
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
outline: none !important;
border-color: #3B82F6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}

View File

@@ -0,0 +1,315 @@
/* Dark Theme Support for SmartSolTech */
/* Base Dark Theme */
html.dark {
color-scheme: dark;
}
.dark body {
background-color: #111827;
color: #f9fafb;
}
/* Navigation Dark Theme */
.dark nav {
background-color: #1f2937;
border-color: #374151;
}
.dark .nav-link {
color: #d1d5db;
}
.dark .nav-link:hover {
color: #60a5fa;
}
.dark .nav-link.active {
color: #60a5fa;
}
/* Sections Dark Theme */
.dark section {
background-color: #111827;
color: #f9fafb;
}
.dark .bg-white {
background-color: #1f2937 !important;
}
.dark .bg-gray-50 {
background-color: #111827 !important;
}
.dark .bg-gray-100 {
background-color: #374151 !important;
}
.dark .bg-gray-900 {
background-color: #030712 !important;
}
/* Text Colors Dark Theme */
.dark .text-gray-900 {
color: #f9fafb !important;
}
.dark .text-gray-800 {
color: #e5e7eb !important;
}
.dark .text-gray-700 {
color: #d1d5db !important;
}
.dark .text-gray-600 {
color: #9ca3af !important;
}
.dark .text-gray-500 {
color: #6b7280 !important;
}
.dark .text-gray-400 {
color: #9ca3af !important;
}
.dark .text-gray-300 {
color: #d1d5db !important;
}
/* Cards Dark Theme */
.dark .card-hover {
background-color: #1f2937;
border-color: #374151;
}
.dark .card-hover:hover {
background-color: #374151;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
}
/* Forms Dark Theme */
.dark .form-input {
background-color: #374151;
border-color: #4b5563;
color: #f9fafb;
}
.dark .form-input:focus {
border-color: #60a5fa;
background-color: #1f2937;
}
.dark .form-input::placeholder {
color: #9ca3af;
}
.dark input,
.dark textarea,
.dark select {
background-color: #374151;
border-color: #4b5563;
color: #f9fafb;
}
.dark input:focus,
.dark textarea:focus,
.dark select:focus {
border-color: #60a5fa;
background-color: #1f2937;
}
/* Borders Dark Theme */
.dark .border-gray-300 {
border-color: #4b5563 !important;
}
.dark .border-gray-200 {
border-color: #374151 !important;
}
.dark .border-t {
border-color: #374151;
}
/* Contact Form Dark Theme */
.dark .contact-form {
background: linear-gradient(145deg, rgba(31,41,55,0.9), rgba(31,41,55,0.95));
border-color: #374151;
}
/* Service Cards Dark Theme */
.dark .service-card {
background: linear-gradient(145deg, rgba(31,41,55,0.8), rgba(31,41,55,0.6));
border-color: #374151;
}
/* Team Cards Dark Theme */
.dark .team-card {
background-color: #1f2937;
border-color: #374151;
}
/* Portfolio Items Dark Theme */
.dark .portfolio-item {
background-color: #1f2937;
}
/* Hero Section Dark Theme */
.dark .hero-section {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
}
/* Shadows Dark Theme */
.dark .shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
}
.dark .shadow-xl {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
}
.dark .shadow-2xl {
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
/* Dropdown Dark Theme */
.dark .dropdown-menu {
background-color: #1f2937;
border-color: #374151;
}
.dark .dropdown-menu a {
color: #d1d5db;
}
.dark .dropdown-menu a:hover {
background-color: #374151;
color: #f9fafb;
}
/* Icons Dark Theme */
.dark .text-blue-600 {
color: #60a5fa !important;
}
.dark .text-purple-600 {
color: #a78bfa !important;
}
.dark .text-green-600 {
color: #34d399 !important;
}
.dark .text-yellow-600 {
color: #fbbf24 !important;
}
/* Buttons Dark Theme */
.dark .btn-primary {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
}
.dark .btn-primary:hover {
background: linear-gradient(135deg, #1d4ed8, #1e40af);
}
/* Footer Dark Theme */
.dark footer {
background-color: #030712;
border-color: #1f2937;
}
.dark .footer-gradient {
background: linear-gradient(135deg, #030712 0%, #111827 100%);
}
/* Scrollbar Dark Theme */
.dark ::-webkit-scrollbar-track {
background: #1f2937;
}
.dark ::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
}
/* Technology Stack Dark Theme */
.dark .tech-stack {
background-color: #030712;
}
.dark .tech-card {
background-color: #1f2937;
border-color: #374151;
}
/* CTA Section Dark Theme */
.dark .cta-section {
background: linear-gradient(135deg, #1e40af 0%, #7c3aed 100%);
}
/* Testimonials Dark Theme */
.dark .testimonial-card {
background: rgba(31, 41, 55, 0.8);
border-color: #374151;
}
/* Alert Messages Dark Theme */
.dark .alert-success {
background: rgba(16, 185, 129, 0.1);
border-color: rgba(16, 185, 129, 0.3);
color: #10b981;
}
.dark .alert-error {
background: rgba(239, 68, 68, 0.1);
border-color: rgba(239, 68, 68, 0.3);
color: #ef4444;
}
/* Mobile Menu Dark Theme */
.dark #mobile-menu {
background-color: #1f2937;
border-color: #374151;
}
/* Language Dropdown Dark Theme */
.dark #mobile-language-menu {
background-color: #1f2937;
border-color: #374151;
}
/* Smooth Theme Transition */
* {
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
/* Print styles for dark theme */
@media print {
.dark * {
background: white !important;
color: black !important;
}
}
/* High contrast mode */
@media (prefers-contrast: high) {
.dark {
color: white !important;
background-color: black !important;
}
.dark .border {
border-width: 2px;
}
}
/* Reduced motion for accessibility */
@media (prefers-reduced-motion: reduce) {
.dark * {
transition: none !important;
animation: none !important;
}
}

View File

@@ -0,0 +1,315 @@
/* Dark Theme Support for SmartSolTech */
/* Base Dark Theme */
html.dark {
color-scheme: dark;
}
.dark body {
background-color: #111827;
color: #f9fafb;
}
/* Navigation Dark Theme */
.dark nav {
background-color: #1f2937;
border-color: #374151;
}
.dark .nav-link {
color: #d1d5db;
}
.dark .nav-link:hover {
color: #60a5fa;
}
.dark .nav-link.active {
color: #60a5fa;
}
/* Sections Dark Theme */
.dark section {
background-color: #111827;
color: #f9fafb;
}
.dark .bg-white {
background-color: #1f2937 !important;
}
.dark .bg-gray-50 {
background-color: #111827 !important;
}
.dark .bg-gray-100 {
background-color: #374151 !important;
}
.dark .bg-gray-900 {
background-color: #030712 !important;
}
/* Text Colors Dark Theme */
.dark .text-gray-900 {
color: #f9fafb !important;
}
.dark .text-gray-800 {
color: #e5e7eb !important;
}
.dark .text-gray-700 {
color: #d1d5db !important;
}
.dark .text-gray-600 {
color: #9ca3af !important;
}
.dark .text-gray-500 {
color: #6b7280 !important;
}
.dark .text-gray-400 {
color: #9ca3af !important;
}
.dark .text-gray-300 {
color: #d1d5db !important;
}
/* Cards Dark Theme */
.dark .card-hover {
background-color: #1f2937;
border-color: #374151;
}
.dark .card-hover:hover {
background-color: #374151;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
}
/* Forms Dark Theme */
.dark .form-input {
background-color: #374151;
border-color: #4b5563;
color: #f9fafb;
}
.dark .form-input:focus {
border-color: #60a5fa;
background-color: #1f2937;
}
.dark .form-input::placeholder {
color: #9ca3af;
}
.dark input,
.dark textarea,
.dark select {
background-color: #374151;
border-color: #4b5563;
color: #f9fafb;
}
.dark input:focus,
.dark textarea:focus,
.dark select:focus {
border-color: #60a5fa;
background-color: #1f2937;
}
/* Borders Dark Theme */
.dark .border-gray-300 {
border-color: #4b5563 !important;
}
.dark .border-gray-200 {
border-color: #374151 !important;
}
.dark .border-t {
border-color: #374151;
}
/* Contact Form Dark Theme */
.dark .contact-form {
background: linear-gradient(145deg, rgba(31,41,55,0.9), rgba(31,41,55,0.95));
border-color: #374151;
}
/* Service Cards Dark Theme */
.dark .service-card {
background: linear-gradient(145deg, rgba(31,41,55,0.8), rgba(31,41,55,0.6));
border-color: #374151;
}
/* Team Cards Dark Theme */
.dark .team-card {
background-color: #1f2937;
border-color: #374151;
}
/* Portfolio Items Dark Theme */
.dark .portfolio-item {
background-color: #1f2937;
}
/* Hero Section Dark Theme */
.dark .hero-section {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
}
/* Shadows Dark Theme */
.dark .shadow-lg {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
}
.dark .shadow-xl {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2);
}
.dark .shadow-2xl {
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}
/* Dropdown Dark Theme */
.dark .dropdown-menu {
background-color: #1f2937;
border-color: #374151;
}
.dark .dropdown-menu a {
color: #d1d5db;
}
.dark .dropdown-menu a:hover {
background-color: #374151;
color: #f9fafb;
}
/* Icons Dark Theme */
.dark .text-blue-600 {
color: #60a5fa !important;
}
.dark .text-purple-600 {
color: #a78bfa !important;
}
.dark .text-green-600 {
color: #34d399 !important;
}
.dark .text-yellow-600 {
color: #fbbf24 !important;
}
/* Buttons Dark Theme */
.dark .btn-primary {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
}
.dark .btn-primary:hover {
background: linear-gradient(135deg, #1d4ed8, #1e40af);
}
/* Footer Dark Theme */
.dark footer {
background-color: #030712;
border-color: #1f2937;
}
.dark .footer-gradient {
background: linear-gradient(135deg, #030712 0%, #111827 100%);
}
/* Scrollbar Dark Theme */
.dark ::-webkit-scrollbar-track {
background: #1f2937;
}
.dark ::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #3b82f6, #1d4ed8);
}
/* Technology Stack Dark Theme */
.dark .tech-stack {
background-color: #030712;
}
.dark .tech-card {
background-color: #1f2937;
border-color: #374151;
}
/* CTA Section Dark Theme */
.dark .cta-section {
background: linear-gradient(135deg, #1e40af 0%, #7c3aed 100%);
}
/* Testimonials Dark Theme */
.dark .testimonial-card {
background: rgba(31, 41, 55, 0.8);
border-color: #374151;
}
/* Alert Messages Dark Theme */
.dark .alert-success {
background: rgba(16, 185, 129, 0.1);
border-color: rgba(16, 185, 129, 0.3);
color: #10b981;
}
.dark .alert-error {
background: rgba(239, 68, 68, 0.1);
border-color: rgba(239, 68, 68, 0.3);
color: #ef4444;
}
/* Mobile Menu Dark Theme */
.dark #mobile-menu {
background-color: #1f2937;
border-color: #374151;
}
/* Language Dropdown Dark Theme */
.dark #mobile-language-menu {
background-color: #1f2937;
border-color: #374151;
}
/* Smooth Theme Transition */
* {
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
/* Print styles for dark theme */
@media print {
.dark * {
background: white !important;
color: black !important;
}
}
/* High contrast mode */
@media (prefers-contrast: high) {
.dark {
color: white !important;
background-color: black !important;
}
.dark .border {
border-width: 2px;
}
}
/* Reduced motion for accessibility */
@media (prefers-reduced-motion: reduce) {
.dark * {
transition: none !important;
animation: none !important;
}
}

View File

@@ -0,0 +1,310 @@
/* SmartSolTech - Design Fixes & Enhancements */
/* Glass effect improvements */
.glass-effect {
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
/* Fallback for browsers that don't support backdrop-filter */
}
/* Support backdrop-filter for modern browsers */
@supports (backdrop-filter: blur(10px)) {
.glass-effect {
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
}
/* Hero section improvements */
.hero-section {
position: relative;
overflow: hidden;
min-height: 100vh;
}
/* Background blob animations */
@keyframes blob {
0% { transform: translate(0px, 0px) scale(1); }
33% { transform: translate(30px, -50px) scale(1.1); }
66% { transform: translate(-20px, 20px) scale(0.9); }
100% { transform: translate(0px, 0px) scale(1); }
}
.animate-blob {
animation: blob 7s infinite;
}
.animation-delay-2000 {
animation-delay: 2s;
}
.animation-delay-4000 {
animation-delay: 4s;
}
/* Enhanced card hover effects */
.card-hover {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
backface-visibility: hidden;
}
.card-hover:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15);
}
/* Portfolio item enhancements */
.portfolio-item {
overflow: hidden;
border-radius: 16px;
position: relative;
}
.portfolio-image {
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.portfolio-item:hover .portfolio-image {
transform: scale(1.1);
}
/* Button improvements */
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8);
border: none;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-primary::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
transition: left 0.5s;
}
.btn-primary:hover::before {
left: 100%;
}
.btn-primary:hover {
background: linear-gradient(135deg, #1D4ED8, #1E40AF);
transform: translateY(-3px);
box-shadow: 0 15px 35px rgba(59, 130, 246, 0.4);
}
/* Navigation improvements */
.nav-link {
position: relative;
transition: all 0.3s ease;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 50%;
width: 0;
height: 2px;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
transition: all 0.3s ease;
transform: translateX(-50%);
}
.nav-link:hover::after,
.nav-link.active::after {
width: 100%;
}
/* Form improvements */
.form-input {
transition: all 0.3s ease;
border: 2px solid #E5E7EB;
background: rgba(255, 255, 255, 0.95);
}
.form-input:focus {
border-color: #3B82F6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
transform: translateY(-1px);
}
/* Contact form styling */
.contact-form {
background: linear-gradient(145deg, rgba(255,255,255,0.9), rgba(255,255,255,0.95));
border: 1px solid rgba(255,255,255,0.3);
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
}
/* CTA section improvements */
.cta-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
}
.cta-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="75" cy="75" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
opacity: 0.3;
}
/* Service cards */
.service-card {
background: linear-gradient(145deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
border: 1px solid rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* Team member cards */
.team-card {
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.95);
}
.team-card:hover {
transform: translateY(-10px);
box-shadow: 0 30px 60px rgba(0,0,0,0.12);
}
/* Technology icons */
.tech-icon {
transition: all 0.3s ease;
}
.tech-icon:hover {
transform: scale(1.1) rotate(5deg);
filter: brightness(1.2);
}
/* Loading states */
.loading {
opacity: 0.7;
pointer-events: none;
}
.loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin: -10px 0 0 -10px;
border: 2px solid #f3f3f3;
border-top: 2px solid #3B82F6;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Mobile optimizations */
@media (max-width: 768px) {
.card-hover:hover {
transform: translateY(-4px) scale(1.01);
}
.btn-primary:hover {
transform: translateY(-2px);
}
.hero-section {
min-height: 80vh;
}
.portfolio-item:hover .portfolio-image {
transform: scale(1.05);
}
}
/* Accessibility improvements */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
button:focus,
input:focus,
textarea:focus,
select:focus,
a:focus {
outline: 2px solid #3B82F6;
outline-offset: 2px;
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Print styles */
@media print {
.no-print {
display: none !important;
}
body {
color: black !important;
background: white !important;
}
}
/* iOS Style Theme Toggle */
.theme-toggle-slider {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Theme toggle background states */
input#theme-toggle:checked + label > div {
background-color: #4F46E5 !important;
}
input#theme-toggle + label > div {
background-color: #D1D5DB;
}
/* Dark mode adjustments for toggle */
.dark input#theme-toggle + label > div {
background-color: #374151;
}
.dark input#theme-toggle:checked + label > div {
background-color: #6366F1 !important;
}
/* Smooth transitions for icons */
.theme-sun-icon,
.theme-moon-icon {
transition: opacity 0.3s ease;
}
/* Dark mode support (if needed) */
@media (prefers-color-scheme: dark) {
.auto-dark {
color: #f9fafb;
background-color: #111827;
}
}

View File

@@ -0,0 +1,310 @@
/* SmartSolTech - Design Fixes & Enhancements */
/* Glass effect improvements */
.glass-effect {
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
/* Fallback for browsers that don't support backdrop-filter */
}
/* Support backdrop-filter for modern browsers */
@supports (backdrop-filter: blur(10px)) {
.glass-effect {
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
}
/* Hero section improvements */
.hero-section {
position: relative;
overflow: hidden;
min-height: 100vh;
}
/* Background blob animations */
@keyframes blob {
0% { transform: translate(0px, 0px) scale(1); }
33% { transform: translate(30px, -50px) scale(1.1); }
66% { transform: translate(-20px, 20px) scale(0.9); }
100% { transform: translate(0px, 0px) scale(1); }
}
.animate-blob {
animation: blob 7s infinite;
}
.animation-delay-2000 {
animation-delay: 2s;
}
.animation-delay-4000 {
animation-delay: 4s;
}
/* Enhanced card hover effects */
.card-hover {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
backface-visibility: hidden;
}
.card-hover:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15);
}
/* Portfolio item enhancements */
.portfolio-item {
overflow: hidden;
border-radius: 16px;
position: relative;
}
.portfolio-image {
transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
.portfolio-item:hover .portfolio-image {
transform: scale(1.1);
}
/* Button improvements */
.btn-primary {
background: linear-gradient(135deg, #3B82F6, #1D4ED8);
border: none;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.btn-primary::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
transition: left 0.5s;
}
.btn-primary:hover::before {
left: 100%;
}
.btn-primary:hover {
background: linear-gradient(135deg, #1D4ED8, #1E40AF);
transform: translateY(-3px);
box-shadow: 0 15px 35px rgba(59, 130, 246, 0.4);
}
/* Navigation improvements */
.nav-link {
position: relative;
transition: all 0.3s ease;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 50%;
width: 0;
height: 2px;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
transition: all 0.3s ease;
transform: translateX(-50%);
}
.nav-link:hover::after,
.nav-link.active::after {
width: 100%;
}
/* Form improvements */
.form-input {
transition: all 0.3s ease;
border: 2px solid #E5E7EB;
background: rgba(255, 255, 255, 0.95);
}
.form-input:focus {
border-color: #3B82F6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
transform: translateY(-1px);
}
/* Contact form styling */
.contact-form {
background: linear-gradient(145deg, rgba(255,255,255,0.9), rgba(255,255,255,0.95));
border: 1px solid rgba(255,255,255,0.3);
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
}
/* CTA section improvements */
.cta-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
}
.cta-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="1" fill="rgba(255,255,255,0.1)"/><circle cx="75" cy="75" r="1" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
opacity: 0.3;
}
/* Service cards */
.service-card {
background: linear-gradient(145deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
border: 1px solid rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
/* Team member cards */
.team-card {
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.95);
}
.team-card:hover {
transform: translateY(-10px);
box-shadow: 0 30px 60px rgba(0,0,0,0.12);
}
/* Technology icons */
.tech-icon {
transition: all 0.3s ease;
}
.tech-icon:hover {
transform: scale(1.1) rotate(5deg);
filter: brightness(1.2);
}
/* Loading states */
.loading {
opacity: 0.7;
pointer-events: none;
}
.loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin: -10px 0 0 -10px;
border: 2px solid #f3f3f3;
border-top: 2px solid #3B82F6;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Mobile optimizations */
@media (max-width: 768px) {
.card-hover:hover {
transform: translateY(-4px) scale(1.01);
}
.btn-primary:hover {
transform: translateY(-2px);
}
.hero-section {
min-height: 80vh;
}
.portfolio-item:hover .portfolio-image {
transform: scale(1.05);
}
}
/* Accessibility improvements */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
button:focus,
input:focus,
textarea:focus,
select:focus,
a:focus {
outline: 2px solid #3B82F6;
outline-offset: 2px;
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Print styles */
@media print {
.no-print {
display: none !important;
}
body {
color: black !important;
background: white !important;
}
}
/* iOS Style Theme Toggle */
.theme-toggle-slider {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Theme toggle background states */
input#theme-toggle:checked + label > div {
background-color: #4F46E5 !important;
}
input#theme-toggle + label > div {
background-color: #D1D5DB;
}
/* Dark mode adjustments for toggle */
.dark input#theme-toggle + label > div {
background-color: #374151;
}
.dark input#theme-toggle:checked + label > div {
background-color: #6366F1 !important;
}
/* Smooth transitions for icons */
.theme-sun-icon,
.theme-moon-icon {
transition: opacity 0.3s ease;
}
/* Dark mode support (if needed) */
@media (prefers-color-scheme: dark) {
.auto-dark {
color: #f9fafb;
background-color: #111827;
}
}

View File

@@ -0,0 +1,554 @@
/* SmartSolTech - Main Styles */
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,554 @@
/* SmartSolTech - Main Styles */
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,570 @@
/* SmartSolTech - Main Styles */
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,570 @@
/* SmartSolTech - Main Styles */
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,573 @@
/* SmartSolTech - Main Styles */
/* Tailwind Base (if not loading properly) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,573 @@
/* SmartSolTech - Main Styles */
/* Tailwind Base (if not loading properly) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2.5rem;
}
}

View File

@@ -0,0 +1,606 @@
/* SmartSolTech - Main Styles */
/* Tailwind Base (if not loading properly) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2rem;
}
}
/* Hero секции - компактные для внутренних страниц */
.hero-section-compact {
min-height: 40vh !important;
max-height: 50vh !important;
padding: 4rem 0 !important;
}
.hero-section-compact h1 {
font-size: 3rem !important;
margin-bottom: 1rem !important;
}
.hero-section-compact p {
font-size: 1.125rem !important;
opacity: 0.9 !important;
}
@media (max-width: 768px) {
.hero-section-compact {
min-height: 30vh !important;
padding: 3rem 0 !important;
}
.hero-section-compact h1 {
font-size: 2.5rem !important;
}
}
/* Полноэкранный Hero только для главной */
.hero-section {
min-height: 100vh !important;
}

View File

@@ -0,0 +1,606 @@
/* SmartSolTech - Main Styles */
/* Tailwind Base (if not loading properly) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
/* CSS Reset and Base */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1f2937;
background-color: #ffffff;
}
/* Root Variables */
:root {
--primary-color: #3B82F6;
--secondary-color: #8B5CF6;
--accent-color: #10B981;
--text-dark: #1f2937;
--text-light: #6b7280;
--bg-light: #f9fafb;
--border-color: #e5e7eb;
}
/* Utility Classes */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
.section-padding {
padding: 4rem 0;
}
/* Navigation */
.navbar {
background: rgba(255, 255, 255, 0.95);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-brand {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
text-decoration: none;
}
.navbar-nav {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-link {
color: #6b7280;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
transition: all 0.3s ease;
}
.nav-link:hover,
.nav-link.active {
color: #3b82f6;
background-color: #eff6ff;
}
.mobile-menu {
overflow: hidden;
}
.mobile-menu.show {
max-height: 500px;
}
/* Button Hover Effects */
.btn-primary {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
transition: all 0.3s ease;
transform: translateY(0);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(59, 130, 246, 0.3);
}
/* Card Hover Effects */
.card-hover {
transition: all 0.3s ease;
transform: translateY(0);
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
/* Portfolio Grid */
.portfolio-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 2rem;
}
.portfolio-item {
border-radius: 1rem;
overflow: hidden;
background: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.portfolio-item:hover {
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.portfolio-image {
position: relative;
overflow: hidden;
aspect-ratio: 16/10;
}
.portfolio-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.portfolio-item:hover .portfolio-image img {
transform: scale(1.05);
}
.portfolio-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(59, 130, 246, 0.8), rgba(139, 92, 246, 0.8));
opacity: 0;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.portfolio-item:hover .portfolio-overlay {
opacity: 1;
}
/* Service Cards */
.service-card {
background: white;
border-radius: 1rem;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary-color);
transform: translateY(-4px);
box-shadow: 0 20px 40px rgba(59, 130, 246, 0.1);
}
.service-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 2rem;
color: white;
transition: all 0.3s ease;
}
.service-card:hover .service-icon {
transform: scale(1.1) rotate(5deg);
}
/* Contact Form */
.contact-form {
background: white;
border-radius: 1rem;
padding: 2rem;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 1.5rem;
}
.form-control {
width: 100%;
padding: 1rem;
border: 2px solid var(--border-color);
border-radius: 0.5rem;
font-size: 1rem;
transition: all 0.3s ease;
background: white;
}
.form-control:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Calculator Styles */
.calculator-step {
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.option-card {
border: 2px solid var(--border-color);
border-radius: 1rem;
padding: 1.5rem;
cursor: pointer;
transition: all 0.3s ease;
background: white;
}
.option-card:hover {
border-color: var(--primary-color);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
}
.option-card.selected {
border-color: var(--primary-color);
background: rgba(59, 130, 246, 0.05);
}
/* Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--border-color);
border-radius: 4px;
overflow: hidden;
margin-bottom: 2rem;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
transition: width 0.3s ease;
}
/* Hero Section Animations */
.hero-content {
animation: heroFadeIn 1s ease-out;
}
@keyframes heroFadeIn {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Parallax Effect */
.parallax {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
/* Scroll Animations */
.fade-in-up {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.fade-in-up.animate {
opacity: 1;
transform: translateY(0);
}
/* Typography */
.gradient-text {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status Badges */
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.status-new {
background: rgba(239, 68, 68, 0.1);
color: #dc2626;
}
.status-in-progress {
background: rgba(245, 158, 11, 0.1);
color: #d97706;
}
.status-completed {
background: rgba(16, 185, 129, 0.1);
color: #059669;
}
/* Responsive Design */
@media (max-width: 768px) {
.portfolio-grid {
grid-template-columns: 1fr;
}
.hero-title {
font-size: 2.5rem;
}
.service-card {
padding: 1.5rem;
}
.calculator-step {
padding: 1rem;
}
}
/* Dark Mode Support */
@media (prefers-color-scheme: dark) {
:root {
--text-dark: #f9fafb;
--text-light: #d1d5db;
--bg-light: #1f2937;
--border-color: #374151;
}
body {
background-color: #111827;
color: var(--text-dark);
}
.card-hover, .service-card, .contact-form, .option-card {
background: #1f2937;
border-color: var(--border-color);
}
.form-control {
background: #374151;
border-color: #4b5563;
color: white;
}
.form-control:focus {
border-color: var(--primary-color);
}
}
/* Print Styles */
@media print {
.navbar, .footer, .contact-form, .mobile-menu {
display: none !important;
}
body {
font-size: 12pt;
line-height: 1.5;
}
.portfolio-item, .service-card {
break-inside: avoid;
margin-bottom: 1rem;
}
}
/* Accessibility */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus styles for better accessibility */
.form-control:focus,
.btn:focus,
.option-card:focus {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
/* Loading States */
.btn-loading {
position: relative;
color: transparent;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
top: 50%;
left: 50%;
margin-left: -8px;
margin-top: -8px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: spin 1s linear infinite;
}
/* Calculator Styles */
.calculator-step {
display: none;
}
.calculator-step.active {
display: block;
}
.service-option,
.complexity-option,
.timeline-option {
cursor: pointer;
transition: all 0.3s ease;
position: relative;
}
.service-option:hover,
.complexity-option:hover,
.timeline-option:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected,
.complexity-option.selected,
.timeline-option.selected {
border-color: #3B82F6 !important;
background-color: #EBF8FF !important;
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.15);
}
.service-option.selected::after,
.complexity-option.selected::after,
.timeline-option.selected::after {
content: '✓';
position: absolute;
top: 0.5rem;
right: 0.5rem;
width: 24px;
height: 24px;
background: #3B82F6;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
/* Price Display Animation */
#final-price {
animation: priceReveal 0.8s ease-in-out;
}
@keyframes priceReveal {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* Calculator Progress Bar */
.calculator-progress {
width: 100%;
height: 4px;
background: #e5e7eb;
border-radius: 2px;
margin-bottom: 2rem;
overflow: hidden;
}
.calculator-progress-bar {
height: 100%;
background: linear-gradient(90deg, #3B82F6, #8B5CF6);
border-radius: 2px;
transition: width 0.3s ease;
width: 33.33%;
}
.calculator-progress-bar.step-2 {
width: 66.66%;
}
.calculator-progress-bar.step-3 {
width: 100%;
}
/* Calculator Mobile Improvements */
@media (max-width: 768px) {
.service-option,
.complexity-option,
.timeline-option {
margin-bottom: 1rem;
}
#final-price {
font-size: 2rem;
}
}
/* Hero секции - компактные для внутренних страниц */
.hero-section-compact {
min-height: 40vh !important;
max-height: 50vh !important;
padding: 4rem 0 !important;
}
.hero-section-compact h1 {
font-size: 3rem !important;
margin-bottom: 1rem !important;
}
.hero-section-compact p {
font-size: 1.125rem !important;
opacity: 0.9 !important;
}
@media (max-width: 768px) {
.hero-section-compact {
min-height: 30vh !important;
padding: 3rem 0 !important;
}
.hero-section-compact h1 {
font-size: 2.5rem !important;
}
}
/* Полноэкранный Hero только для главной */
.hero-section {
min-height: 100vh !important;
}

View File

@@ -0,0 +1,4 @@
<svg width="144" height="144" xmlns="http://www.w3.org/2000/svg">
<rect width="144" height="144" fill="#3b82f6" rx="24"/>
<text x="72" y="82" text-anchor="middle" font-family="Arial" font-size="36" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 250 B

View File

@@ -0,0 +1,4 @@
<svg width="144" height="144" xmlns="http://www.w3.org/2000/svg">
<rect width="144" height="144" fill="#3b82f6" rx="24"/>
<text x="72" y="82" text-anchor="middle" font-family="Arial" font-size="36" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 250 B

View File

@@ -0,0 +1,4 @@
<svg width="192" height="192" xmlns="http://www.w3.org/2000/svg">
<rect width="192" height="192" fill="#3b82f6" rx="32"/>
<text x="96" y="110" text-anchor="middle" font-family="Arial" font-size="48" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@@ -0,0 +1,4 @@
<svg width="192" height="192" xmlns="http://www.w3.org/2000/svg">
<rect width="192" height="192" fill="#3b82f6" rx="32"/>
<text x="96" y="110" text-anchor="middle" font-family="Arial" font-size="48" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@@ -0,0 +1,4 @@
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" fill="#3b82f6" rx="8"/>
<text x="20" y="26" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 245 B

View File

@@ -0,0 +1,4 @@
<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" fill="#3b82f6" rx="8"/>
<text x="20" y="26" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white">ST</text>
</svg>

After

Width:  |  Height:  |  Size: 245 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#f3e8ff"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#7c3aed">Corporate Website</text>
</svg>

After

Width:  |  Height:  |  Size: 242 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#f3e8ff"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#7c3aed">Corporate Website</text>
</svg>

After

Width:  |  Height:  |  Size: 242 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#f3f4f6"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#6b7280">E-commerce Project</text>
</svg>

After

Width:  |  Height:  |  Size: 243 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#f3f4f6"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#6b7280">E-commerce Project</text>
</svg>

After

Width:  |  Height:  |  Size: 243 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#e0f2fe"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#0369a1">Fitness App Project</text>
</svg>

After

Width:  |  Height:  |  Size: 244 B

View File

@@ -0,0 +1,4 @@
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<rect width="400" height="300" fill="#e0f2fe"/>
<text x="200" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#0369a1">Fitness App Project</text>
</svg>

After

Width:  |  Height:  |  Size: 244 B

View File

@@ -0,0 +1,399 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.0';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.0';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.0';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
const DYNAMIC_ROUTES = [
'/about',
'/services',
'/portfolio',
'/calculator',
'/contact'
];
// API endpoints to cache
const API_CACHE_PATTERNS = [
/^\/api\/portfolio/,
/^\/api\/services/,
/^\/api\/calculator\/services/
];
// Install event - cache static files
self.addEventListener('install', event => {
console.log('Service Worker: Installing...');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Caching static files');
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log('Service Worker: Static files cached');
return self.skipWaiting();
})
.catch(error => {
console.error('Service Worker: Error caching static files', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('Service Worker: Activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Deleting old cache', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('Service Worker: Activated');
return self.clients.claim();
})
);
});
// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== 'GET') {
return;
}
// Skip Chrome extension requests
if (url.protocol === 'chrome-extension:') {
return;
}
// Handle different types of requests
if (isStaticFile(request.url)) {
event.respondWith(cacheFirst(request));
} else if (isAPIRequest(request.url)) {
event.respondWith(networkFirst(request));
} else if (isDynamicRoute(request.url)) {
event.respondWith(staleWhileRevalidate(request));
} else {
event.respondWith(networkFirst(request));
}
});
// Cache strategies
async function cacheFirst(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
console.error('Cache first strategy failed:', error);
return new Response('Offline', { status: 503 });
}
}
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.log('Network first: Falling back to cache for', request.url);
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return offline page for navigation requests
if (request.mode === 'navigate') {
return caches.match('/offline.html') || new Response('Offline', {
status: 503,
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Network Error', { status: 503 });
}
}
async function staleWhileRevalidate(request) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
});
return cachedResponse || fetchPromise;
}
// Helper functions
function isStaticFile(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/images/') ||
url.includes('/fonts/') ||
url.includes('googleapis.com') ||
url.includes('cdnjs.cloudflare.com');
}
function isAPIRequest(url) {
return url.includes('/api/') ||
API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}
function isDynamicRoute(url) {
const pathname = new URL(url).pathname;
return DYNAMIC_ROUTES.includes(pathname) ||
pathname.startsWith('/portfolio/') ||
pathname.startsWith('/services/');
}
// Background sync for form submissions
self.addEventListener('sync', event => {
console.log('Service Worker: Background sync triggered', event.tag);
if (event.tag === 'contact-form-sync') {
event.waitUntil(syncContactForms());
}
});
async function syncContactForms() {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const requests = await cache.keys();
const contactRequests = requests.filter(request =>
request.url.includes('/api/contact/submit')
);
for (const request of contactRequests) {
try {
await fetch(request);
await cache.delete(request);
console.log('Contact form synced successfully');
} catch (error) {
console.error('Failed to sync contact form:', error);
}
}
} catch (error) {
console.error('Background sync failed:', error);
}
}
// Push notification handling
self.addEventListener('push', event => {
console.log('Service Worker: Push received', event);
let data = {};
if (event.data) {
data = event.data.json();
}
const title = data.title || 'SmartSolTech';
const options = {
body: data.body || 'You have a new notification',
icon: '/images/icon-192x192.png',
badge: '/images/icon-72x72.png',
tag: data.tag || 'default',
data: data.url || '/',
actions: [
{
action: 'open',
title: '열기',
icon: '/images/icon-open.png'
},
{
action: 'close',
title: '닫기',
icon: '/images/icon-close.png'
}
],
requireInteraction: data.requireInteraction || false,
silent: data.silent || false,
vibrate: data.vibrate || [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Notification click handling
self.addEventListener('notificationclick', event => {
console.log('Service Worker: Notification clicked', event);
event.notification.close();
if (event.action === 'close') {
return;
}
const url = event.notification.data || '/';
event.waitUntil(
clients.matchAll({ type: 'window' }).then(clientList => {
// Check if window is already open
for (const client of clientList) {
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
// Open new window
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
// Handle messages from main thread
self.addEventListener('message', event => {
console.log('Service Worker: Message received', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
cacheUrls(event.data.urls);
}
});
async function cacheUrls(urls) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
await cache.addAll(urls);
console.log('URLs cached successfully:', urls);
} catch (error) {
console.error('Failed to cache URLs:', error);
}
}
// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
console.log('Service Worker: Periodic sync triggered', event.tag);
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
async function syncContent() {
try {
// Fetch fresh portfolio and services data
const portfolioResponse = await fetch('/api/portfolio?featured=true');
const servicesResponse = await fetch('/api/services?featured=true');
if (portfolioResponse.ok && servicesResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
cache.put('/api/services?featured=true', servicesResponse.clone());
console.log('Content synced successfully');
}
} catch (error) {
console.error('Content sync failed:', error);
}
}
// Cache management utilities
async function cleanupCaches() {
const cacheNames = await caches.keys();
const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
return Promise.all(
cacheNames.map(cacheName => {
if (!currentCaches.includes(cacheName)) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}
// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
const cache = await caches.open(cacheName);
const keys = await cache.keys();
if (keys.length > maxItems) {
const keysToDelete = keys.slice(0, keys.length - maxItems);
return Promise.all(keysToDelete.map(key => cache.delete(key)));
}
}
// Performance monitoring
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
const start = performance.now();
event.respondWith(
fetch(event.request).then(response => {
const duration = performance.now() - start;
// Log slow API requests
if (duration > 2000) {
console.warn('Slow API request:', event.request.url, duration + 'ms');
}
return response;
})
);
}
});
// Error tracking
self.addEventListener('error', event => {
console.error('Service Worker error:', event.error);
// Could send to analytics service
});
self.addEventListener('unhandledrejection', event => {
console.error('Service Worker unhandled rejection:', event.reason);
// Could send to analytics service
});

View File

@@ -0,0 +1,399 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.1';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.1';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.1';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
const DYNAMIC_ROUTES = [
'/about',
'/services',
'/portfolio',
'/calculator',
'/contact'
];
// API endpoints to cache
const API_CACHE_PATTERNS = [
/^\/api\/portfolio/,
/^\/api\/services/,
/^\/api\/calculator\/services/
];
// Install event - cache static files
self.addEventListener('install', event => {
console.log('Service Worker: Installing...');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Caching static files');
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log('Service Worker: Static files cached');
return self.skipWaiting();
})
.catch(error => {
console.error('Service Worker: Error caching static files', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('Service Worker: Activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Deleting old cache', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('Service Worker: Activated');
return self.clients.claim();
})
);
});
// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== 'GET') {
return;
}
// Skip Chrome extension requests
if (url.protocol === 'chrome-extension:') {
return;
}
// Handle different types of requests
if (isStaticFile(request.url)) {
event.respondWith(cacheFirst(request));
} else if (isAPIRequest(request.url)) {
event.respondWith(networkFirst(request));
} else if (isDynamicRoute(request.url)) {
event.respondWith(staleWhileRevalidate(request));
} else {
event.respondWith(networkFirst(request));
}
});
// Cache strategies
async function cacheFirst(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
console.error('Cache first strategy failed:', error);
return new Response('Offline', { status: 503 });
}
}
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.log('Network first: Falling back to cache for', request.url);
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return offline page for navigation requests
if (request.mode === 'navigate') {
return caches.match('/offline.html') || new Response('Offline', {
status: 503,
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Network Error', { status: 503 });
}
}
async function staleWhileRevalidate(request) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
});
return cachedResponse || fetchPromise;
}
// Helper functions
function isStaticFile(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/images/') ||
url.includes('/fonts/') ||
url.includes('googleapis.com') ||
url.includes('cdnjs.cloudflare.com');
}
function isAPIRequest(url) {
return url.includes('/api/') ||
API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}
function isDynamicRoute(url) {
const pathname = new URL(url).pathname;
return DYNAMIC_ROUTES.includes(pathname) ||
pathname.startsWith('/portfolio/') ||
pathname.startsWith('/services/');
}
// Background sync for form submissions
self.addEventListener('sync', event => {
console.log('Service Worker: Background sync triggered', event.tag);
if (event.tag === 'contact-form-sync') {
event.waitUntil(syncContactForms());
}
});
async function syncContactForms() {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const requests = await cache.keys();
const contactRequests = requests.filter(request =>
request.url.includes('/api/contact/submit')
);
for (const request of contactRequests) {
try {
await fetch(request);
await cache.delete(request);
console.log('Contact form synced successfully');
} catch (error) {
console.error('Failed to sync contact form:', error);
}
}
} catch (error) {
console.error('Background sync failed:', error);
}
}
// Push notification handling
self.addEventListener('push', event => {
console.log('Service Worker: Push received', event);
let data = {};
if (event.data) {
data = event.data.json();
}
const title = data.title || 'SmartSolTech';
const options = {
body: data.body || 'You have a new notification',
icon: '/images/icon-192x192.png',
badge: '/images/icon-72x72.png',
tag: data.tag || 'default',
data: data.url || '/',
actions: [
{
action: 'open',
title: '열기',
icon: '/images/icon-open.png'
},
{
action: 'close',
title: '닫기',
icon: '/images/icon-close.png'
}
],
requireInteraction: data.requireInteraction || false,
silent: data.silent || false,
vibrate: data.vibrate || [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Notification click handling
self.addEventListener('notificationclick', event => {
console.log('Service Worker: Notification clicked', event);
event.notification.close();
if (event.action === 'close') {
return;
}
const url = event.notification.data || '/';
event.waitUntil(
clients.matchAll({ type: 'window' }).then(clientList => {
// Check if window is already open
for (const client of clientList) {
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
// Open new window
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
// Handle messages from main thread
self.addEventListener('message', event => {
console.log('Service Worker: Message received', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
cacheUrls(event.data.urls);
}
});
async function cacheUrls(urls) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
await cache.addAll(urls);
console.log('URLs cached successfully:', urls);
} catch (error) {
console.error('Failed to cache URLs:', error);
}
}
// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
console.log('Service Worker: Periodic sync triggered', event.tag);
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
async function syncContent() {
try {
// Fetch fresh portfolio and services data
const portfolioResponse = await fetch('/api/portfolio?featured=true');
const servicesResponse = await fetch('/api/services?featured=true');
if (portfolioResponse.ok && servicesResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
cache.put('/api/services?featured=true', servicesResponse.clone());
console.log('Content synced successfully');
}
} catch (error) {
console.error('Content sync failed:', error);
}
}
// Cache management utilities
async function cleanupCaches() {
const cacheNames = await caches.keys();
const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
return Promise.all(
cacheNames.map(cacheName => {
if (!currentCaches.includes(cacheName)) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}
// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
const cache = await caches.open(cacheName);
const keys = await cache.keys();
if (keys.length > maxItems) {
const keysToDelete = keys.slice(0, keys.length - maxItems);
return Promise.all(keysToDelete.map(key => cache.delete(key)));
}
}
// Performance monitoring
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
const start = performance.now();
event.respondWith(
fetch(event.request).then(response => {
const duration = performance.now() - start;
// Log slow API requests
if (duration > 2000) {
console.warn('Slow API request:', event.request.url, duration + 'ms');
}
return response;
})
);
}
});
// Error tracking
self.addEventListener('error', event => {
console.error('Service Worker error:', event.error);
// Could send to analytics service
});
self.addEventListener('unhandledrejection', event => {
console.error('Service Worker unhandled rejection:', event.reason);
// Could send to analytics service
});

View File

@@ -0,0 +1,399 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.1';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.1';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.1';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
const DYNAMIC_ROUTES = [
'/about',
'/services',
'/portfolio',
'/calculator',
'/contact'
];
// API endpoints to cache
const API_CACHE_PATTERNS = [
/^\/api\/portfolio/,
/^\/api\/services/,
/^\/api\/calculator\/services/
];
// Install event - cache static files
self.addEventListener('install', event => {
console.log('Service Worker: Installing...');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Caching static files');
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log('Service Worker: Static files cached');
return self.skipWaiting();
})
.catch(error => {
console.error('Service Worker: Error caching static files', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('Service Worker: Activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Deleting old cache', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('Service Worker: Activated');
return self.clients.claim();
})
);
});
// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== 'GET') {
return;
}
// Skip Chrome extension requests
if (url.protocol === 'chrome-extension:') {
return;
}
// Handle different types of requests
if (isStaticFile(request.url)) {
event.respondWith(cacheFirst(request));
} else if (isAPIRequest(request.url)) {
event.respondWith(networkFirst(request));
} else if (isDynamicRoute(request.url)) {
event.respondWith(staleWhileRevalidate(request));
} else {
event.respondWith(networkFirst(request));
}
});
// Cache strategies
async function cacheFirst(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
console.error('Cache first strategy failed:', error);
return new Response('Offline', { status: 503 });
}
}
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.log('Network first: Falling back to cache for', request.url);
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return offline page for navigation requests
if (request.mode === 'navigate') {
return caches.match('/offline.html') || new Response('Offline', {
status: 503,
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Network Error', { status: 503 });
}
}
async function staleWhileRevalidate(request) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
});
return cachedResponse || fetchPromise;
}
// Helper functions
function isStaticFile(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/images/') ||
url.includes('/fonts/') ||
url.includes('googleapis.com') ||
url.includes('cdnjs.cloudflare.com');
}
function isAPIRequest(url) {
return url.includes('/api/') ||
API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}
function isDynamicRoute(url) {
const pathname = new URL(url).pathname;
return DYNAMIC_ROUTES.includes(pathname) ||
pathname.startsWith('/portfolio/') ||
pathname.startsWith('/services/');
}
// Background sync for form submissions
self.addEventListener('sync', event => {
console.log('Service Worker: Background sync triggered', event.tag);
if (event.tag === 'contact-form-sync') {
event.waitUntil(syncContactForms());
}
});
async function syncContactForms() {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const requests = await cache.keys();
const contactRequests = requests.filter(request =>
request.url.includes('/api/contact/submit')
);
for (const request of contactRequests) {
try {
await fetch(request);
await cache.delete(request);
console.log('Contact form synced successfully');
} catch (error) {
console.error('Failed to sync contact form:', error);
}
}
} catch (error) {
console.error('Background sync failed:', error);
}
}
// Push notification handling
self.addEventListener('push', event => {
console.log('Service Worker: Push received', event);
let data = {};
if (event.data) {
data = event.data.json();
}
const title = data.title || 'SmartSolTech';
const options = {
body: data.body || 'You have a new notification',
icon: '/images/icon-192x192.png',
badge: '/images/icon-72x72.png',
tag: data.tag || 'default',
data: data.url || '/',
actions: [
{
action: 'open',
title: '열기',
icon: '/images/icon-open.png'
},
{
action: 'close',
title: '닫기',
icon: '/images/icon-close.png'
}
],
requireInteraction: data.requireInteraction || false,
silent: data.silent || false,
vibrate: data.vibrate || [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Notification click handling
self.addEventListener('notificationclick', event => {
console.log('Service Worker: Notification clicked', event);
event.notification.close();
if (event.action === 'close') {
return;
}
const url = event.notification.data || '/';
event.waitUntil(
clients.matchAll({ type: 'window' }).then(clientList => {
// Check if window is already open
for (const client of clientList) {
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
// Open new window
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
// Handle messages from main thread
self.addEventListener('message', event => {
console.log('Service Worker: Message received', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
cacheUrls(event.data.urls);
}
});
async function cacheUrls(urls) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
await cache.addAll(urls);
console.log('URLs cached successfully:', urls);
} catch (error) {
console.error('Failed to cache URLs:', error);
}
}
// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
console.log('Service Worker: Periodic sync triggered', event.tag);
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
async function syncContent() {
try {
// Fetch fresh portfolio and services data
const portfolioResponse = await fetch('/api/portfolio?featured=true');
const servicesResponse = await fetch('/api/services?featured=true');
if (portfolioResponse.ok && servicesResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
cache.put('/api/services?featured=true', servicesResponse.clone());
console.log('Content synced successfully');
}
} catch (error) {
console.error('Content sync failed:', error);
}
}
// Cache management utilities
async function cleanupCaches() {
const cacheNames = await caches.keys();
const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
return Promise.all(
cacheNames.map(cacheName => {
if (!currentCaches.includes(cacheName)) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}
// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
const cache = await caches.open(cacheName);
const keys = await cache.keys();
if (keys.length > maxItems) {
const keysToDelete = keys.slice(0, keys.length - maxItems);
return Promise.all(keysToDelete.map(key => cache.delete(key)));
}
}
// Performance monitoring
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
const start = performance.now();
event.respondWith(
fetch(event.request).then(response => {
const duration = performance.now() - start;
// Log slow API requests
if (duration > 2000) {
console.warn('Slow API request:', event.request.url, duration + 'ms');
}
return response;
})
);
}
});
// Error tracking
self.addEventListener('error', event => {
console.error('Service Worker error:', event.error);
// Could send to analytics service
});
self.addEventListener('unhandledrejection', event => {
console.error('Service Worker unhandled rejection:', event.reason);
// Could send to analytics service
});

View File

@@ -0,0 +1,407 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.1';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.1';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.1';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
const DYNAMIC_ROUTES = [
'/about',
'/services',
'/portfolio',
'/calculator',
'/contact'
];
// API endpoints to cache
const API_CACHE_PATTERNS = [
/^\/api\/portfolio/,
/^\/api\/services/,
/^\/api\/calculator\/services/
];
// Install event - cache static files
self.addEventListener('install', event => {
console.log('Service Worker: Installing...');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Caching static files');
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log('Service Worker: Static files cached');
return self.skipWaiting();
})
.catch(error => {
console.error('Service Worker: Error caching static files', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('Service Worker: Activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Deleting old cache', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('Service Worker: Activated');
return self.clients.claim();
})
);
});
// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== 'GET') {
return;
}
// Skip Chrome extension requests
if (url.protocol === 'chrome-extension:') {
return;
}
// Handle different types of requests
if (isStaticFile(request.url)) {
event.respondWith(cacheFirst(request));
} else if (isAPIRequest(request.url)) {
event.respondWith(networkFirst(request));
} else if (isDynamicRoute(request.url)) {
event.respondWith(staleWhileRevalidate(request));
} else {
event.respondWith(networkFirst(request));
}
});
// Cache strategies
async function cacheFirst(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
console.error('Cache first strategy failed:', error);
return new Response('Offline', { status: 503 });
}
}
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.log('Network first: Falling back to cache for', request.url);
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return offline page for navigation requests
if (request.mode === 'navigate') {
return caches.match('/offline.html') || new Response('Offline', {
status: 503,
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Network Error', { status: 503 });
}
}
async function staleWhileRevalidate(request) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse && networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
}).catch(error => {
console.log('staleWhileRevalidate fetch failed:', error);
return null;
});
return cachedResponse || fetchPromise || new Response('Not available', { status: 503 });
} catch (error) {
console.error('staleWhileRevalidate error:', error);
return new Response('Service unavailable', { status: 503 });
}
}
// Helper functions
function isStaticFile(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/images/') ||
url.includes('/fonts/') ||
url.includes('googleapis.com') ||
url.includes('cdnjs.cloudflare.com');
}
function isAPIRequest(url) {
return url.includes('/api/') ||
API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}
function isDynamicRoute(url) {
const pathname = new URL(url).pathname;
return DYNAMIC_ROUTES.includes(pathname) ||
pathname.startsWith('/portfolio/') ||
pathname.startsWith('/services/');
}
// Background sync for form submissions
self.addEventListener('sync', event => {
console.log('Service Worker: Background sync triggered', event.tag);
if (event.tag === 'contact-form-sync') {
event.waitUntil(syncContactForms());
}
});
async function syncContactForms() {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const requests = await cache.keys();
const contactRequests = requests.filter(request =>
request.url.includes('/api/contact/submit')
);
for (const request of contactRequests) {
try {
await fetch(request);
await cache.delete(request);
console.log('Contact form synced successfully');
} catch (error) {
console.error('Failed to sync contact form:', error);
}
}
} catch (error) {
console.error('Background sync failed:', error);
}
}
// Push notification handling
self.addEventListener('push', event => {
console.log('Service Worker: Push received', event);
let data = {};
if (event.data) {
data = event.data.json();
}
const title = data.title || 'SmartSolTech';
const options = {
body: data.body || 'You have a new notification',
icon: '/images/icon-192x192.png',
badge: '/images/icon-72x72.png',
tag: data.tag || 'default',
data: data.url || '/',
actions: [
{
action: 'open',
title: '열기',
icon: '/images/icon-open.png'
},
{
action: 'close',
title: '닫기',
icon: '/images/icon-close.png'
}
],
requireInteraction: data.requireInteraction || false,
silent: data.silent || false,
vibrate: data.vibrate || [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Notification click handling
self.addEventListener('notificationclick', event => {
console.log('Service Worker: Notification clicked', event);
event.notification.close();
if (event.action === 'close') {
return;
}
const url = event.notification.data || '/';
event.waitUntil(
clients.matchAll({ type: 'window' }).then(clientList => {
// Check if window is already open
for (const client of clientList) {
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
// Open new window
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
// Handle messages from main thread
self.addEventListener('message', event => {
console.log('Service Worker: Message received', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
cacheUrls(event.data.urls);
}
});
async function cacheUrls(urls) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
await cache.addAll(urls);
console.log('URLs cached successfully:', urls);
} catch (error) {
console.error('Failed to cache URLs:', error);
}
}
// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
console.log('Service Worker: Periodic sync triggered', event.tag);
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
async function syncContent() {
try {
// Fetch fresh portfolio and services data
const portfolioResponse = await fetch('/api/portfolio?featured=true');
const servicesResponse = await fetch('/api/services?featured=true');
if (portfolioResponse.ok && servicesResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
cache.put('/api/services?featured=true', servicesResponse.clone());
console.log('Content synced successfully');
}
} catch (error) {
console.error('Content sync failed:', error);
}
}
// Cache management utilities
async function cleanupCaches() {
const cacheNames = await caches.keys();
const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
return Promise.all(
cacheNames.map(cacheName => {
if (!currentCaches.includes(cacheName)) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}
// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
const cache = await caches.open(cacheName);
const keys = await cache.keys();
if (keys.length > maxItems) {
const keysToDelete = keys.slice(0, keys.length - maxItems);
return Promise.all(keysToDelete.map(key => cache.delete(key)));
}
}
// Performance monitoring
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
const start = performance.now();
event.respondWith(
fetch(event.request).then(response => {
const duration = performance.now() - start;
// Log slow API requests
if (duration > 2000) {
console.warn('Slow API request:', event.request.url, duration + 'ms');
}
return response;
})
);
}
});
// Error tracking
self.addEventListener('error', event => {
console.error('Service Worker error:', event.error);
// Could send to analytics service
});
self.addEventListener('unhandledrejection', event => {
console.error('Service Worker unhandled rejection:', event.reason);
// Could send to analytics service
});

View File

@@ -0,0 +1,407 @@
// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.1';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.1';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.1';
// Files to cache immediately
const STATIC_FILES = [
'/',
'/css/main.css',
'/css/fixes.css',
'/css/dark-theme.css',
'/js/main.js',
'/images/logo.png',
'/images/icon-192x192.png',
'/images/icon-144x144.png',
'/manifest.json',
'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
'https://unpkg.com/aos@2.3.1/dist/aos.css',
'https://unpkg.com/aos@2.3.1/dist/aos.js'
];
// Routes to cache dynamically
const DYNAMIC_ROUTES = [
'/about',
'/services',
'/portfolio',
'/calculator',
'/contact'
];
// API endpoints to cache
const API_CACHE_PATTERNS = [
/^\/api\/portfolio/,
/^\/api\/services/,
/^\/api\/calculator\/services/
];
// Install event - cache static files
self.addEventListener('install', event => {
console.log('Service Worker: Installing...');
event.waitUntil(
caches.open(STATIC_CACHE_NAME)
.then(cache => {
console.log('Service Worker: Caching static files');
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log('Service Worker: Static files cached');
return self.skipWaiting();
})
.catch(error => {
console.error('Service Worker: Error caching static files', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('Service Worker: Activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== STATIC_CACHE_NAME &&
cacheName !== DYNAMIC_CACHE_NAME) {
console.log('Service Worker: Deleting old cache', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('Service Worker: Activated');
return self.clients.claim();
})
);
});
// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
// Skip non-GET requests
if (request.method !== 'GET') {
return;
}
// Skip Chrome extension requests
if (url.protocol === 'chrome-extension:') {
return;
}
// Handle different types of requests
if (isStaticFile(request.url)) {
event.respondWith(cacheFirst(request));
} else if (isAPIRequest(request.url)) {
event.respondWith(networkFirst(request));
} else if (isDynamicRoute(request.url)) {
event.respondWith(staleWhileRevalidate(request));
} else {
event.respondWith(networkFirst(request));
}
});
// Cache strategies
async function cacheFirst(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
return networkResponse;
} catch (error) {
console.error('Cache first strategy failed:', error);
return new Response('Offline', { status: 503 });
}
}
async function networkFirst(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.log('Network first: Falling back to cache for', request.url);
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
// Return offline page for navigation requests
if (request.mode === 'navigate') {
return caches.match('/offline.html') || new Response('Offline', {
status: 503,
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Network Error', { status: 503 });
}
}
async function staleWhileRevalidate(request) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const cachedResponse = await cache.match(request);
const fetchPromise = fetch(request).then(networkResponse => {
if (networkResponse && networkResponse.ok) {
cache.put(request, networkResponse.clone());
}
return networkResponse;
}).catch(error => {
console.log('staleWhileRevalidate fetch failed:', error);
return null;
});
return cachedResponse || fetchPromise || new Response('Not available', { status: 503 });
} catch (error) {
console.error('staleWhileRevalidate error:', error);
return new Response('Service unavailable', { status: 503 });
}
}
// Helper functions
function isStaticFile(url) {
return url.includes('/css/') ||
url.includes('/js/') ||
url.includes('/images/') ||
url.includes('/fonts/') ||
url.includes('googleapis.com') ||
url.includes('cdnjs.cloudflare.com');
}
function isAPIRequest(url) {
return url.includes('/api/') ||
API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}
function isDynamicRoute(url) {
const pathname = new URL(url).pathname;
return DYNAMIC_ROUTES.includes(pathname) ||
pathname.startsWith('/portfolio/') ||
pathname.startsWith('/services/');
}
// Background sync for form submissions
self.addEventListener('sync', event => {
console.log('Service Worker: Background sync triggered', event.tag);
if (event.tag === 'contact-form-sync') {
event.waitUntil(syncContactForms());
}
});
async function syncContactForms() {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
const requests = await cache.keys();
const contactRequests = requests.filter(request =>
request.url.includes('/api/contact/submit')
);
for (const request of contactRequests) {
try {
await fetch(request);
await cache.delete(request);
console.log('Contact form synced successfully');
} catch (error) {
console.error('Failed to sync contact form:', error);
}
}
} catch (error) {
console.error('Background sync failed:', error);
}
}
// Push notification handling
self.addEventListener('push', event => {
console.log('Service Worker: Push received', event);
let data = {};
if (event.data) {
data = event.data.json();
}
const title = data.title || 'SmartSolTech';
const options = {
body: data.body || 'You have a new notification',
icon: '/images/icon-192x192.png',
badge: '/images/icon-72x72.png',
tag: data.tag || 'default',
data: data.url || '/',
actions: [
{
action: 'open',
title: '열기',
icon: '/images/icon-open.png'
},
{
action: 'close',
title: '닫기',
icon: '/images/icon-close.png'
}
],
requireInteraction: data.requireInteraction || false,
silent: data.silent || false,
vibrate: data.vibrate || [200, 100, 200]
};
event.waitUntil(
self.registration.showNotification(title, options)
);
});
// Notification click handling
self.addEventListener('notificationclick', event => {
console.log('Service Worker: Notification clicked', event);
event.notification.close();
if (event.action === 'close') {
return;
}
const url = event.notification.data || '/';
event.waitUntil(
clients.matchAll({ type: 'window' }).then(clientList => {
// Check if window is already open
for (const client of clientList) {
if (client.url === url && 'focus' in client) {
return client.focus();
}
}
// Open new window
if (clients.openWindow) {
return clients.openWindow(url);
}
})
);
});
// Handle messages from main thread
self.addEventListener('message', event => {
console.log('Service Worker: Message received', event.data);
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
cacheUrls(event.data.urls);
}
});
async function cacheUrls(urls) {
try {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
await cache.addAll(urls);
console.log('URLs cached successfully:', urls);
} catch (error) {
console.error('Failed to cache URLs:', error);
}
}
// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
console.log('Service Worker: Periodic sync triggered', event.tag);
if (event.tag === 'content-sync') {
event.waitUntil(syncContent());
}
});
async function syncContent() {
try {
// Fetch fresh portfolio and services data
const portfolioResponse = await fetch('/api/portfolio?featured=true');
const servicesResponse = await fetch('/api/services?featured=true');
if (portfolioResponse.ok && servicesResponse.ok) {
const cache = await caches.open(DYNAMIC_CACHE_NAME);
cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
cache.put('/api/services?featured=true', servicesResponse.clone());
console.log('Content synced successfully');
}
} catch (error) {
console.error('Content sync failed:', error);
}
}
// Cache management utilities
async function cleanupCaches() {
const cacheNames = await caches.keys();
const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
return Promise.all(
cacheNames.map(cacheName => {
if (!currentCaches.includes(cacheName)) {
console.log('Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
}
// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
const cache = await caches.open(cacheName);
const keys = await cache.keys();
if (keys.length > maxItems) {
const keysToDelete = keys.slice(0, keys.length - maxItems);
return Promise.all(keysToDelete.map(key => cache.delete(key)));
}
}
// Performance monitoring
self.addEventListener('fetch', event => {
if (event.request.url.includes('/api/')) {
const start = performance.now();
event.respondWith(
fetch(event.request).then(response => {
const duration = performance.now() - start;
// Log slow API requests
if (duration > 2000) {
console.warn('Slow API request:', event.request.url, duration + 'ms');
}
return response;
})
);
}
});
// Error tracking
self.addEventListener('error', event => {
console.error('Service Worker error:', event.error);
// Could send to analytics service
});
self.addEventListener('unhandledrejection', event => {
console.error('Service Worker unhandled rejection:', event.reason);
// Could send to analytics service
});