Redesign site to dark SaaS aesthetic with original brand colors
Full visual overhaul inspired by SummonAIKit: dark near-black background, glassmorphism nav, dot grid backgrounds, gradient hero text, glowing cards, and animated glow orbs. Uses Syne (display) + DM Sans (body) fonts. Retains original green (#5CB82C) primary and orange (#F7931E) accent brand colors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
56933f6e5c
commit
f8626ee987
|
|
@ -2,49 +2,179 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--color-void: #07070f;
|
||||
--color-surface: #0f0f1a;
|
||||
--color-surface-50: #16162a;
|
||||
--color-surface-100: #1c1c2e;
|
||||
--color-border: rgba(92, 184, 44, 0.2);
|
||||
--color-border-dim: rgba(255, 255, 255, 0.06);
|
||||
--color-primary: #5CB82C;
|
||||
--color-primary-light: #86efac;
|
||||
--color-accent: #F7931E;
|
||||
--color-text: #e8e6f0;
|
||||
--color-text-muted: #8b8ca8;
|
||||
}
|
||||
|
||||
html { scroll-behavior: smooth; }
|
||||
|
||||
body {
|
||||
background-color: var(--color-void);
|
||||
color: var(--color-text);
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: 'Syne', sans-serif;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: rgba(92, 184, 44, 0.35);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar { width: 6px; }
|
||||
::-webkit-scrollbar-track { background: var(--color-void); }
|
||||
::-webkit-scrollbar-thumb { background: var(--color-primary); border-radius: 3px; }
|
||||
::-webkit-scrollbar-thumb:hover { background: var(--color-primary-light); }
|
||||
}
|
||||
|
||||
@layer components {
|
||||
/* Buttons */
|
||||
.btn {
|
||||
@apply px-4 py-2 rounded-lg font-medium transition-colors duration-200;
|
||||
@apply inline-flex items-center justify-center px-5 py-2.5 rounded-lg font-semibold transition-all duration-200 text-sm tracking-wide;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply bg-primary-600 text-white hover:bg-primary-700;
|
||||
background: linear-gradient(135deg, #5CB82C, #4CA324);
|
||||
@apply text-white;
|
||||
box-shadow: 0 0 20px rgba(92, 184, 44, 0.3);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background: linear-gradient(135deg, #6fcf37, #5CB82C);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 0 30px rgba(92, 184, 44, 0.45);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply bg-gray-200 text-gray-800 hover:bg-gray-300;
|
||||
@apply bg-surface-100 text-gray-300 border border-white/10 hover:border-white/20 hover:text-white;
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
@apply border-2 border-primary-600 text-primary-600 hover:bg-primary-600 hover:text-white;
|
||||
@apply border text-primary-400 hover:text-primary-300;
|
||||
border-color: rgba(92, 184, 44, 0.4);
|
||||
}
|
||||
.btn-outline:hover {
|
||||
border-color: rgba(92, 184, 44, 0.7);
|
||||
background: rgba(92, 184, 44, 0.07);
|
||||
}
|
||||
|
||||
.btn-accent {
|
||||
@apply bg-accent-500 text-white hover:bg-accent-600;
|
||||
background: linear-gradient(135deg, #F7931E, #ea7c0c);
|
||||
@apply text-white font-bold;
|
||||
box-shadow: 0 0 20px rgba(247, 147, 30, 0.25);
|
||||
}
|
||||
.btn-accent:hover {
|
||||
background: linear-gradient(135deg, #f9a94a, #F7931E);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 0 30px rgba(247, 147, 30, 0.4);
|
||||
}
|
||||
|
||||
.btn-accent-outline {
|
||||
@apply border-2 border-accent-500 text-accent-500 hover:bg-accent-500 hover:text-white;
|
||||
.btn-ghost {
|
||||
@apply text-gray-400 hover:text-white hover:bg-white/5;
|
||||
}
|
||||
|
||||
/* Cards */
|
||||
.card {
|
||||
@apply bg-white rounded-xl shadow-md p-6;
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border-dim);
|
||||
@apply rounded-xl p-6 transition-all duration-300;
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent outline-none transition-all;
|
||||
.card-hover {
|
||||
@apply card;
|
||||
}
|
||||
.card-hover:hover {
|
||||
border-color: rgba(92, 184, 44, 0.3);
|
||||
box-shadow: 0 0 30px rgba(92, 184, 44, 0.07), 0 8px 32px rgba(0,0,0,0.4);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Form Elements */
|
||||
.input {
|
||||
background: var(--color-surface-50);
|
||||
border: 1px solid var(--color-border-dim);
|
||||
@apply w-full px-4 py-3 rounded-lg text-gray-200 placeholder-gray-600 outline-none transition-all duration-200;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
}
|
||||
.input:focus {
|
||||
border-color: rgba(92, 184, 44, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(92, 184, 44, 0.1);
|
||||
background: var(--color-surface-100);
|
||||
}
|
||||
.input::placeholder { color: #4a4a6a; }
|
||||
|
||||
.label {
|
||||
@apply block text-sm font-medium text-gray-700 mb-1;
|
||||
@apply block text-sm font-medium text-gray-400 mb-2;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
.nav-link {
|
||||
@apply text-gray-600 hover:text-primary-600 font-medium transition-colors;
|
||||
@apply text-gray-400 hover:text-white font-medium transition-colors duration-200 text-sm;
|
||||
}
|
||||
.nav-link-active {
|
||||
@apply text-white font-semibold;
|
||||
}
|
||||
|
||||
.nav-link-active {
|
||||
@apply text-primary-600 font-semibold;
|
||||
/* Gradient text */
|
||||
.gradient-text {
|
||||
background: linear-gradient(135deg, #86efac 0%, #F7931E 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.gradient-text-green {
|
||||
background: linear-gradient(135deg, #bbf7d0 0%, #5CB82C 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Dot grid */
|
||||
.dot-grid {
|
||||
background-image: radial-gradient(circle, rgba(92, 184, 44, 0.15) 1px, transparent 1px);
|
||||
background-size: 28px 28px;
|
||||
}
|
||||
|
||||
/* Badge */
|
||||
.badge {
|
||||
@apply inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold tracking-wider;
|
||||
}
|
||||
.badge-primary {
|
||||
background: rgba(92, 184, 44, 0.12);
|
||||
border: 1px solid rgba(92, 184, 44, 0.3);
|
||||
@apply text-primary-300;
|
||||
}
|
||||
.badge-accent {
|
||||
background: rgba(247, 147, 30, 0.1);
|
||||
border: 1px solid rgba(247, 147, 30, 0.3);
|
||||
@apply text-accent-300;
|
||||
}
|
||||
.badge-red {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
border: 1px solid rgba(239, 68, 68, 0.25);
|
||||
@apply text-red-400;
|
||||
}
|
||||
|
||||
/* Avatar */
|
||||
.avatar {
|
||||
background: linear-gradient(135deg, #5CB82C, #F7931E);
|
||||
@apply rounded-full flex items-center justify-center text-white font-bold flex-shrink-0;
|
||||
font-family: 'Syne', sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,11 +183,41 @@
|
|||
opacity: 0;
|
||||
transition: opacity 200ms ease-in;
|
||||
}
|
||||
.htmx-request .htmx-indicator { opacity: 1; }
|
||||
.htmx-request.htmx-indicator { opacity: 1; }
|
||||
|
||||
.htmx-request .htmx-indicator {
|
||||
opacity: 1;
|
||||
/* Prose overrides for dark theme */
|
||||
.prose-dark { color: #c4c2d4; }
|
||||
.prose-dark h1, .prose-dark h2, .prose-dark h3,
|
||||
.prose-dark h4, .prose-dark h5, .prose-dark h6 {
|
||||
color: #f1f0ff;
|
||||
font-family: 'Syne', sans-serif;
|
||||
}
|
||||
.prose-dark a { color: #86efac; }
|
||||
.prose-dark a:hover { color: #bbf7d0; }
|
||||
.prose-dark strong { color: #e8e6f0; }
|
||||
.prose-dark code {
|
||||
background: rgba(92, 184, 44, 0.1);
|
||||
border: 1px solid rgba(92, 184, 44, 0.2);
|
||||
color: #86efac;
|
||||
padding: 0.125rem 0.375rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.prose-dark pre {
|
||||
background: #0f0f1a;
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
.prose-dark blockquote {
|
||||
border-left-color: #5CB82C;
|
||||
color: #8b8ca8;
|
||||
}
|
||||
.prose-dark hr { border-color: rgba(255,255,255,0.06); }
|
||||
|
||||
.htmx-request.htmx-indicator {
|
||||
opacity: 1;
|
||||
/* Animations */
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% { opacity: 0.4; }
|
||||
50% { opacity: 0.9; }
|
||||
}
|
||||
.pulse-glow-anim { animation: pulse-glow 3s ease-in-out infinite; }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -6,9 +6,13 @@ module.exports = {
|
|||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
display: ['Syne', 'sans-serif'],
|
||||
body: ['DM Sans', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f0fdf4',
|
||||
50: '#f0fdf4',
|
||||
100: '#dcfce7',
|
||||
200: '#bbf7d0',
|
||||
300: '#86efac',
|
||||
|
|
@ -20,7 +24,7 @@ module.exports = {
|
|||
900: '#1F4D0F',
|
||||
},
|
||||
accent: {
|
||||
50: '#fff7ed',
|
||||
50: '#fff7ed',
|
||||
100: '#ffedd5',
|
||||
200: '#fed7aa',
|
||||
300: '#fdba74',
|
||||
|
|
@ -30,8 +34,21 @@ module.exports = {
|
|||
700: '#c2640a',
|
||||
800: '#9a4f0d',
|
||||
900: '#7c400e',
|
||||
}
|
||||
}
|
||||
},
|
||||
surface: {
|
||||
DEFAULT: '#0f0f1a',
|
||||
50: '#16162a',
|
||||
100: '#1c1c2e',
|
||||
200: '#22223a',
|
||||
},
|
||||
void: '#07070f',
|
||||
},
|
||||
boxShadow: {
|
||||
'glow-sm': '0 0 15px rgba(92, 184, 44, 0.25)',
|
||||
'glow': '0 0 30px rgba(92, 184, 44, 0.3)',
|
||||
'glow-lg': '0 0 60px rgba(92, 184, 44, 0.35)',
|
||||
'glow-accent': '0 0 30px rgba(247, 147, 30, 0.25)',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
|
|
|||
|
|
@ -3,103 +3,88 @@
|
|||
{% block title %}About Us{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">About DirectLX</h1>
|
||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
||||
We're a team of passionate developers dedicated to building software that makes a difference.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="relative py-28 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="badge badge-primary mb-6">Our Story</div>
|
||||
<h1 class="text-5xl md:text-6xl font-extrabold mb-6 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
About <span class="gradient-text">DirectLX</span>
|
||||
</h1>
|
||||
<p class="text-lg max-w-2xl mx-auto" style="color: #8b8ca8;">
|
||||
A team of passionate engineers dedicated to building software that genuinely makes a difference.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Our Story -->
|
||||
<section class="py-20">
|
||||
<!-- Story + Values -->
|
||||
<section class="py-20" style="background: #0a0a14;">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-14 items-start">
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-6">Our Story</h2>
|
||||
<p class="text-gray-600 mb-4">
|
||||
DirectLX was founded with a simple mission: to help businesses succeed through technology.
|
||||
We believe that great software isn't just about code—it's about understanding problems
|
||||
and crafting solutions that truly work.
|
||||
</p>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Over the years, we've had the privilege of working with startups, growing businesses,
|
||||
and established enterprises across various industries. Each project has taught us
|
||||
something new and reinforced our commitment to excellence.
|
||||
</p>
|
||||
<p class="text-gray-600">
|
||||
Today, we continue to push boundaries, embrace new technologies, and deliver
|
||||
solutions that exceed expectations. Our journey is far from over, and we're
|
||||
excited about what the future holds.
|
||||
</p>
|
||||
<h2 class="text-3xl font-bold mb-6" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Our Story</h2>
|
||||
<div class="space-y-4 text-base leading-relaxed" style="color: #8b8ca8;">
|
||||
<p>
|
||||
DirectLX was founded with a simple mission: help businesses succeed through technology. We believe great software isn't just about code — it's about understanding problems and crafting solutions that truly work.
|
||||
</p>
|
||||
<p>
|
||||
Over the years, we've had the privilege of working with startups, growing businesses, and established enterprises across various industries. Each project has taught us something new and reinforced our commitment to excellence.
|
||||
</p>
|
||||
<p>
|
||||
Today, we continue to push boundaries, embrace new technologies, and deliver solutions that exceed expectations. Our journey is far from over — and we're excited about what comes next.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gradient-to-br from-primary-500 to-primary-700 rounded-2xl p-8 text-white">
|
||||
<h3 class="text-2xl font-bold mb-6">Our Values</h3>
|
||||
<ul class="space-y-4">
|
||||
<li class="flex items-start">
|
||||
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
|
||||
<!-- Values card -->
|
||||
<div class="card p-8" style="border: 1px solid rgba(92,184,44,0.25);">
|
||||
<h3 class="text-xl font-bold mb-7" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Our Values</h3>
|
||||
<ul class="space-y-5">
|
||||
{% set values = [
|
||||
('Quality First', 'We never compromise on quality, even under pressure.'),
|
||||
('Transparency', 'Open communication and honest relationships with every client.'),
|
||||
('Continuous Learning', 'Always evolving — embracing new tools, patterns, and ideas.'),
|
||||
('Client Success', 'Your success is our success. Full stop.'),
|
||||
] %}
|
||||
{% for title, desc in values %}
|
||||
<li class="flex items-start gap-4">
|
||||
<div class="w-6 h-6 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5"
|
||||
style="background: rgba(92,184,44,0.15); border: 1px solid rgba(92,184,44,0.3);">
|
||||
<svg class="w-3.5 h-3.5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<strong class="block">Quality First</strong>
|
||||
<span class="text-primary-100">We never compromise on quality, even under pressure.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<div>
|
||||
<strong class="block">Transparency</strong>
|
||||
<span class="text-primary-100">Open communication and honest relationships with clients.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<div>
|
||||
<strong class="block">Continuous Learning</strong>
|
||||
<span class="text-primary-100">Always evolving and improving our skills.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class="flex items-start">
|
||||
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<div>
|
||||
<strong class="block">Client Success</strong>
|
||||
<span class="text-primary-100">Your success is our success.</span>
|
||||
<div class="font-semibold text-sm mb-0.5" style="color: #e8e6f0; font-family: 'Syne', sans-serif;">{{ title }}</div>
|
||||
<div class="text-sm" style="color: #8b8ca8;">{{ desc }}</div>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Team Section -->
|
||||
<section class="bg-gray-100 py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Meet Our Team</h2>
|
||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
||||
A diverse group of talented individuals united by a shared passion for building great software.
|
||||
</p>
|
||||
<!-- Team -->
|
||||
<section class="py-20 relative">
|
||||
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-14">
|
||||
<div class="badge badge-primary mb-5">The Team</div>
|
||||
<h2 class="text-3xl font-bold" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Meet the people<br><span class="gradient-text">behind the code</span></h2>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div class="card text-center">
|
||||
<div class="w-24 h-24 bg-gradient-to-br from-primary-400 to-primary-600 rounded-full mx-auto mb-4 flex items-center justify-center text-white text-2xl font-bold">
|
||||
JH
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900">Johannes</h3>
|
||||
<p class="text-accent-500 mb-3">Founder & CEO</p>
|
||||
<p class="text-gray-600 text-sm">
|
||||
<div class="flex justify-center">
|
||||
<div class="card-hover p-8 text-center max-w-xs w-full">
|
||||
<div class="w-20 h-20 avatar text-2xl font-bold mx-auto mb-5">JH</div>
|
||||
<h3 class="text-lg font-bold mb-1" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Johannes</h3>
|
||||
<p class="text-sm font-medium mb-4 gradient-text">Founder & CEO</p>
|
||||
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||
25+ years in software development. Passionate about clean code and scalable architectures.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -107,19 +92,26 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Mission Section -->
|
||||
<section class="py-20">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-6">Our Mission</h2>
|
||||
<p class="text-xl text-gray-600 mb-8">
|
||||
"To empower businesses with innovative software solutions that drive growth,
|
||||
improve efficiency, and create lasting value. We believe technology should
|
||||
be an enabler, not a barrier, and we're committed to making that a reality
|
||||
for every client we work with."
|
||||
</p>
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-accent px-8 py-3 text-lg">
|
||||
Let's Work Together
|
||||
</a>
|
||||
<!-- Mission -->
|
||||
<section class="py-24" style="background: #0a0a14;">
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<!-- Quote card -->
|
||||
<div class="inline-block p-px rounded-2xl w-full"
|
||||
style="background: linear-gradient(135deg, rgba(92,184,44,0.35), rgba(247,147,30,0.15));">
|
||||
<div class="rounded-2xl px-10 py-14" style="background: #0f0f1a;">
|
||||
<div class="text-4xl mb-6 gradient-text" style="font-family: 'Syne', sans-serif;">“</div>
|
||||
<p class="text-lg md:text-xl leading-relaxed mb-8" style="color: #c4c2d4;">
|
||||
To empower businesses with innovative software solutions that drive growth, improve efficiency, and create lasting value. Technology should be an enabler — not a barrier.
|
||||
</p>
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary px-8 py-3.5">
|
||||
Let's Work Together
|
||||
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -4,35 +4,41 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}DirectLX{% endblock %} | DirectLX.dev</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700;800&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;1,9..40,300;1,9..40,400&display=swap" rel="stylesheet">
|
||||
<link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet">
|
||||
<script src="{{ url_for('static', filename='js/htmx.min.js') }}"></script>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body class="min-h-screen bg-gray-50 flex flex-col">
|
||||
<body class="min-h-screen flex flex-col" style="background-color: #07070f; font-family: 'DM Sans', sans-serif;">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="bg-white shadow-sm sticky top-0 z-50">
|
||||
<nav class="sticky top-0 z-50 border-b" style="background: rgba(7,7,15,0.85); backdrop-filter: blur(20px); border-color: rgba(255,255,255,0.06);">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-20">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex items-center">
|
||||
<a href="{{ url_for('index') }}" class="flex items-center">
|
||||
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-14">
|
||||
<a href="{{ url_for('index') }}" class="flex items-center gap-3 group">
|
||||
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-9 opacity-90 group-hover:opacity-100 transition-opacity">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="hidden md:flex items-center space-x-8">
|
||||
<a href="{{ url_for('index') }}" class="nav-link {% if request.endpoint == 'index' %}nav-link-active{% endif %}">Home</a>
|
||||
<a href="{{ url_for('about') }}" class="nav-link {% if request.endpoint == 'about' %}nav-link-active{% endif %}">About</a>
|
||||
<a href="{{ url_for('services') }}" class="nav-link {% if request.endpoint == 'services' %}nav-link-active{% endif %}">Services</a>
|
||||
<a href="{{ url_for('blog_index') }}" class="nav-link {% if 'blog' in request.endpoint %}nav-link-active{% endif %}">Blog</a>
|
||||
<a href="{{ url_for('forum_index') }}" class="nav-link {% if 'forum' in request.endpoint %}nav-link-active{% endif %}">Forum</a>
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary">Contact</a>
|
||||
<div class="hidden md:flex items-center gap-1">
|
||||
<a href="{{ url_for('index') }}" class="nav-link px-4 py-2 rounded-lg hover:bg-white/5 {% if request.endpoint == 'index' %}nav-link-active bg-white/5{% endif %}">Home</a>
|
||||
<a href="{{ url_for('about') }}" class="nav-link px-4 py-2 rounded-lg hover:bg-white/5 {% if request.endpoint == 'about' %}nav-link-active bg-white/5{% endif %}">About</a>
|
||||
<a href="{{ url_for('services') }}" class="nav-link px-4 py-2 rounded-lg hover:bg-white/5 {% if request.endpoint == 'services' %}nav-link-active bg-white/5{% endif %}">Services</a>
|
||||
<a href="{{ url_for('blog_index') }}" class="nav-link px-4 py-2 rounded-lg hover:bg-white/5 {% if 'blog' in request.endpoint %}nav-link-active bg-white/5{% endif %}">Blog</a>
|
||||
<a href="{{ url_for('forum_index') }}" class="nav-link px-4 py-2 rounded-lg hover:bg-white/5 {% if 'forum' in request.endpoint %}nav-link-active bg-white/5{% endif %}">Forum</a>
|
||||
<div class="ml-4 pl-4" style="border-left: 1px solid rgba(255,255,255,0.08);">
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary text-sm">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile menu button -->
|
||||
<div class="md:hidden flex items-center">
|
||||
<button id="mobile-menu-btn" class="text-gray-600 hover:text-primary-600 focus:outline-none">
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<button id="mobile-menu-btn" class="text-gray-400 hover:text-white p-2 rounded-lg hover:bg-white/5 transition-colors">
|
||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</button>
|
||||
|
|
@ -41,14 +47,16 @@
|
|||
</div>
|
||||
|
||||
<!-- Mobile Navigation -->
|
||||
<div id="mobile-menu" class="hidden md:hidden bg-white border-t">
|
||||
<div class="px-4 py-3 space-y-3">
|
||||
<a href="{{ url_for('index') }}" class="block nav-link">Home</a>
|
||||
<a href="{{ url_for('about') }}" class="block nav-link">About</a>
|
||||
<a href="{{ url_for('services') }}" class="block nav-link">Services</a>
|
||||
<a href="{{ url_for('blog_index') }}" class="block nav-link">Blog</a>
|
||||
<a href="{{ url_for('forum_index') }}" class="block nav-link">Forum</a>
|
||||
<a href="{{ url_for('contact') }}" class="block btn btn-primary text-center">Contact</a>
|
||||
<div id="mobile-menu" class="hidden md:hidden border-t" style="background: rgba(7,7,15,0.95); border-color: rgba(255,255,255,0.06);">
|
||||
<div class="px-4 py-4 space-y-1">
|
||||
<a href="{{ url_for('index') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">Home</a>
|
||||
<a href="{{ url_for('about') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">About</a>
|
||||
<a href="{{ url_for('services') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">Services</a>
|
||||
<a href="{{ url_for('blog_index') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">Blog</a>
|
||||
<a href="{{ url_for('forum_index') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">Forum</a>
|
||||
<div class="pt-2">
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary w-full">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
@ -56,9 +64,12 @@
|
|||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-4 w-full">
|
||||
{% for category, message in messages %}
|
||||
<div class="p-4 rounded-lg mb-2 {% if category == 'error' %}bg-red-100 text-red-700{% elif category == 'success' %}bg-green-100 text-green-700{% else %}bg-blue-100 text-blue-700{% endif %}">
|
||||
<div class="p-4 rounded-xl mb-2 text-sm font-medium
|
||||
{% if category == 'error' %}border border-red-500/30 bg-red-500/10 text-red-300
|
||||
{% elif category == 'success' %}border border-emerald-500/30 bg-emerald-500/10 text-emerald-300
|
||||
{% else %}border border-primary-500/30 bg-primary-500/10 text-primary-300{% endif %}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
@ -72,43 +83,45 @@
|
|||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-gray-900 text-gray-300 mt-auto">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<footer style="background: #0a0a14; border-top: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-14">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-10">
|
||||
<div class="col-span-1 md:col-span-2">
|
||||
<div class="flex items-center mb-4">
|
||||
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-14">
|
||||
</div>
|
||||
<p class="text-gray-400 max-w-md">
|
||||
Building innovative software solutions that drive business growth.
|
||||
We specialize in custom development, consulting, and technical excellence.
|
||||
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-9 mb-5 opacity-80">
|
||||
<p class="text-sm leading-relaxed" style="color: #6b6b8a; max-width: 300px;">
|
||||
Building innovative software solutions that drive business growth. Custom development, consulting, and technical excellence.
|
||||
</p>
|
||||
<!-- Status badge -->
|
||||
<div class="mt-6 inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-xs" style="background: rgba(247,147,30,0.08); border: 1px solid rgba(247,147,30,0.2); color: #fdba74;">
|
||||
<span class="w-1.5 h-1.5 rounded-full bg-accent-400 pulse-glow-anim"></span>
|
||||
All systems operational
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-white font-semibold mb-4">Quick Links</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="{{ url_for('index') }}" class="hover:text-white transition-colors">Home</a></li>
|
||||
<li><a href="{{ url_for('about') }}" class="hover:text-white transition-colors">About</a></li>
|
||||
<li><a href="{{ url_for('services') }}" class="hover:text-white transition-colors">Services</a></li>
|
||||
<li><a href="{{ url_for('blog_index') }}" class="hover:text-white transition-colors">Blog</a></li>
|
||||
<h3 class="text-xs font-semibold tracking-widest uppercase mb-5" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Company</h3>
|
||||
<ul class="space-y-3">
|
||||
<li><a href="{{ url_for('index') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Home</a></li>
|
||||
<li><a href="{{ url_for('about') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">About</a></li>
|
||||
<li><a href="{{ url_for('services') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Services</a></li>
|
||||
<li><a href="{{ url_for('blog_index') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Blog</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-white font-semibold mb-4">Community</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="{{ url_for('forum_index') }}" class="hover:text-white transition-colors">Forum</a></li>
|
||||
<li><a href="{{ url_for('contact') }}" class="hover:text-white transition-colors">Contact</a></li>
|
||||
<h3 class="text-xs font-semibold tracking-widest uppercase mb-5" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Community</h3>
|
||||
<ul class="space-y-3">
|
||||
<li><a href="{{ url_for('forum_index') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Forum</a></li>
|
||||
<li><a href="{{ url_for('contact') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-500">
|
||||
<p>© {{ now.year if now else '2024' }} DirectLX.dev. All rights reserved.</p>
|
||||
<div class="mt-12 pt-8 flex flex-col sm:flex-row justify-between items-center gap-4" style="border-top: 1px solid rgba(255,255,255,0.05);">
|
||||
<p class="text-xs" style="color: #4a4a6a;">© {{ now.year if now else '2024' }} DirectLX.dev. All rights reserved.</p>
|
||||
<p class="text-xs" style="color: #4a4a6a;">Built with precision & care.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Mobile menu toggle
|
||||
document.getElementById('mobile-menu-btn').addEventListener('click', function() {
|
||||
document.getElementById('mobile-menu').classList.toggle('hidden');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,41 +3,42 @@
|
|||
{% block title %}Blog{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-primary-600 to-primary-800 text-white py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4">Our Blog</h1>
|
||||
<p class="text-xl text-primary-100 max-w-2xl mx-auto">
|
||||
Insights, tutorials, and thoughts on software development, technology, and industry trends.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Search Section -->
|
||||
<section class="py-8 bg-gray-100">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-xl mx-auto">
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
name="search"
|
||||
placeholder="Search posts..."
|
||||
class="input pl-12"
|
||||
hx-get="{{ url_for('blog_search') }}"
|
||||
hx-trigger="keyup changed delay:500ms"
|
||||
hx-target="#blog-posts"
|
||||
hx-swap="innerHTML">
|
||||
<svg class="w-5 h-5 text-gray-400 absolute left-4 top-1/2 transform -translate-y-1/2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<!-- Hero -->
|
||||
<section class="relative py-24 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[350px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="badge badge-primary mb-6">Blog</div>
|
||||
<h1 class="text-5xl md:text-6xl font-extrabold mb-5 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Insights & <span class="gradient-text">Ideas</span>
|
||||
</h1>
|
||||
<p class="text-lg max-w-xl mx-auto mb-10" style="color: #8b8ca8;">
|
||||
Tutorials, thoughts on software development, and industry perspectives.
|
||||
</p>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="max-w-md mx-auto relative">
|
||||
<input type="text"
|
||||
name="search"
|
||||
placeholder="Search posts…"
|
||||
class="input pl-11 pr-4 py-3.5"
|
||||
hx-get="{{ url_for('blog_search') }}"
|
||||
hx-trigger="keyup changed delay:500ms"
|
||||
hx-target="#blog-posts"
|
||||
hx-swap="innerHTML">
|
||||
<svg class="w-4 h-4 absolute left-4 top-1/2 -translate-y-1/2 pointer-events-none" style="color: #6b6b8a;"
|
||||
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Blog Posts -->
|
||||
<section class="py-16">
|
||||
<section class="py-16 pb-28" style="background: #0a0a14;">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div id="blog-posts">
|
||||
{% include "blog/partials/post_list.html" %}
|
||||
|
|
@ -45,14 +46,14 @@
|
|||
|
||||
<!-- Load More -->
|
||||
{% if posts and posts|length >= 10 %}
|
||||
<div class="text-center mt-12">
|
||||
<div class="text-center mt-14">
|
||||
<button hx-get="{{ url_for('blog_load_more', page=2) }}"
|
||||
hx-target="#blog-posts"
|
||||
hx-swap="beforeend"
|
||||
hx-trigger="click"
|
||||
class="btn btn-outline px-8 py-3">
|
||||
class="btn btn-outline px-10 py-3.5">
|
||||
<span class="htmx-indicator mr-2">
|
||||
<svg class="animate-spin h-5 w-5 inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<svg class="animate-spin h-4 w-4 inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
|
|
@ -63,4 +64,5 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,38 +1,40 @@
|
|||
{% if posts %}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{% for post in posts %}
|
||||
<article class="card hover:shadow-lg transition-shadow">
|
||||
<div class="text-sm text-gray-500 mb-2">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-2">
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="hover:text-primary-600 transition-colors">
|
||||
<article class="card-hover flex flex-col p-7 group">
|
||||
<div class="text-xs font-medium tracking-wide mb-4" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
<h2 class="text-lg font-bold mb-3 leading-snug" style="font-family: 'Syne', sans-serif;">
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-gray-100 hover:text-primary-300 transition-colors">
|
||||
{{ post.title }}
|
||||
</a>
|
||||
</h2>
|
||||
<p class="text-gray-600 mb-4 line-clamp-3">
|
||||
{{ post.excerpt or post.content[:150] }}{% if post.content|length > 150 %}...{% endif %}
|
||||
<p class="text-sm leading-relaxed mb-6 flex-grow" style="color: #8b8ca8;">
|
||||
{{ post.excerpt or post.content[:150] }}{% if post.content|length > 150 %}…{% endif %}
|
||||
</p>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center text-sm text-gray-500">
|
||||
<div class="w-6 h-6 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 text-xs font-semibold mr-2">
|
||||
{{ post.author.username[0].upper() }}
|
||||
</div>
|
||||
{{ post.author.username }}
|
||||
<div class="flex items-center justify-between mt-auto pt-5" style="border-top: 1px solid rgba(255,255,255,0.05);">
|
||||
<div class="flex items-center gap-2.5">
|
||||
<div class="avatar w-7 h-7 text-xs">{{ post.author.username[0].upper() }}</div>
|
||||
<span class="text-xs" style="color: #6b6b8a;">{{ post.author.username }}</span>
|
||||
</div>
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-primary-600 hover:text-primary-700 font-medium text-sm">
|
||||
Read more →
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-xs font-semibold text-primary-400 hover:text-primary-300 flex items-center gap-1 transition-colors">
|
||||
Read more
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-16">
|
||||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z" />
|
||||
<div class="text-center py-20">
|
||||
<div class="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-5"
|
||||
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||
<svg class="w-8 h-8 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No posts yet</h3>
|
||||
<p class="text-gray-600">Check back soon for new content!</p>
|
||||
<h3 class="text-xl font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No posts yet</h3>
|
||||
<p class="text-sm" style="color: #6b6b8a;">Check back soon for new content!</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -3,45 +3,57 @@
|
|||
{% block title %}{{ post.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<article class="py-16">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<!-- Post Header -->
|
||||
|
||||
<article class="py-16 pb-28" style="background: #0a0a14;">
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
||||
<!-- Back link -->
|
||||
<div class="mb-10">
|
||||
<a href="{{ url_for('blog_index') }}" class="inline-flex items-center gap-2 text-sm font-medium text-primary-400 hover:text-primary-300 transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16l-4-4m0 0l4-4m-4 4h18"/>
|
||||
</svg>
|
||||
Back to Blog
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Post header -->
|
||||
<header class="mb-12">
|
||||
<div class="flex items-center text-sm text-gray-500 mb-4">
|
||||
<a href="{{ url_for('blog_index') }}" class="hover:text-primary-600">← Back to Blog</a>
|
||||
</div>
|
||||
<h1 class="text-4xl md:text-5xl font-bold text-gray-900 mb-6">{{ post.title }}</h1>
|
||||
<div class="flex items-center text-gray-600">
|
||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold mr-3">
|
||||
{{ post.author.username[0].upper() }}
|
||||
</div>
|
||||
<div class="badge badge-primary mb-6">Article</div>
|
||||
<h1 class="text-4xl md:text-5xl font-extrabold mb-7 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
{{ post.title }}
|
||||
</h1>
|
||||
<div class="flex items-center gap-4 pb-8" style="border-bottom: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="avatar w-10 h-10 text-sm font-bold">{{ post.author.username[0].upper() }}</div>
|
||||
<div>
|
||||
<div class="font-medium text-gray-900">{{ post.author.username }}</div>
|
||||
<div class="text-sm">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
<div class="text-sm font-semibold" style="color: #e8e6f0;">{{ post.author.username }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Post Content -->
|
||||
<div class="prose prose-lg max-w-none">
|
||||
<!-- Content -->
|
||||
<div class="prose-dark leading-relaxed" style="font-size: 1.0625rem; line-height: 1.8;">
|
||||
{{ post.content | safe }}
|
||||
</div>
|
||||
|
||||
<!-- Post Footer -->
|
||||
<footer class="mt-12 pt-8 border-t border-gray-200">
|
||||
<!-- Footer -->
|
||||
<footer class="mt-14 pt-8" style="border-top: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
{% if post.updated_at and post.updated_at != post.created_at %}
|
||||
<p class="text-sm text-gray-500">
|
||||
Last updated: {{ post.updated_at.strftime('%B %d, %Y') }}
|
||||
</p>
|
||||
<p class="text-xs" style="color: #6b6b8a;">Last updated: {{ post.updated_at.strftime('%B %d, %Y') }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a href="{{ url_for('blog_index') }}" class="btn btn-secondary">
|
||||
← Back to Blog
|
||||
<a href="{{ url_for('blog_index') }}" class="btn btn-outline">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16l-4-4m0 0l4-4m-4 4h18"/>
|
||||
</svg>
|
||||
Back to Blog
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,133 +3,143 @@
|
|||
{% block title %}Contact{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">Get in Touch</h1>
|
||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
||||
Have a project in mind? We'd love to hear from you.
|
||||
Send us a message and we'll respond as soon as possible.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="relative py-28 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="badge badge-primary mb-6">Get in Touch</div>
|
||||
<h1 class="text-5xl md:text-6xl font-extrabold mb-6 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Let's <span class="gradient-text">talk</span>
|
||||
</h1>
|
||||
<p class="text-lg max-w-xl mx-auto" style="color: #8b8ca8;">
|
||||
Have a project in mind? We'd love to hear from you. Send us a message and we'll get back within 24 hours.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contact Section -->
|
||||
<section class="py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||
<section class="py-12 pb-28" style="background: #0a0a14;">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-5 gap-10">
|
||||
|
||||
<!-- Contact Form -->
|
||||
<div class="card">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Send us a Message</h2>
|
||||
<form id="contact-form"
|
||||
hx-post="{{ url_for('contact_submit') }}"
|
||||
hx-target="#form-response"
|
||||
hx-swap="innerHTML"
|
||||
class="space-y-6">
|
||||
<div>
|
||||
<label for="name" class="label">Your Name</label>
|
||||
<input type="text" id="name" name="name" required
|
||||
class="input"
|
||||
placeholder="John Doe">
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="label">Email Address</label>
|
||||
<input type="email" id="email" name="email" required
|
||||
class="input"
|
||||
placeholder="john@example.com">
|
||||
</div>
|
||||
<div>
|
||||
<label for="subject" class="label">Subject</label>
|
||||
<input type="text" id="subject" name="subject" required
|
||||
class="input"
|
||||
placeholder="Project Inquiry">
|
||||
</div>
|
||||
<div>
|
||||
<label for="message" class="label">Message</label>
|
||||
<textarea id="message" name="message" rows="5" required
|
||||
class="input resize-none"
|
||||
placeholder="Tell us about your project..."></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-accent w-full py-3">
|
||||
<span class="htmx-indicator">
|
||||
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
Send Message
|
||||
</button>
|
||||
</form>
|
||||
<div id="form-response" class="mt-4"></div>
|
||||
<div class="lg:col-span-3">
|
||||
<div class="card p-8" style="border: 1px solid rgba(92,184,44,0.2);">
|
||||
<h2 class="text-xl font-bold mb-7" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Send a Message</h2>
|
||||
<form id="contact-form"
|
||||
hx-post="{{ url_for('contact_submit') }}"
|
||||
hx-target="#form-response"
|
||||
hx-swap="innerHTML"
|
||||
class="space-y-5">
|
||||
<div>
|
||||
<label for="name" class="label">Your Name</label>
|
||||
<input type="text" id="name" name="name" required class="input" placeholder="Jane Smith">
|
||||
</div>
|
||||
<div>
|
||||
<label for="email" class="label">Email Address</label>
|
||||
<input type="email" id="email" name="email" required class="input" placeholder="jane@company.com">
|
||||
</div>
|
||||
<div>
|
||||
<label for="subject" class="label">Subject</label>
|
||||
<input type="text" id="subject" name="subject" required class="input" placeholder="Project Inquiry">
|
||||
</div>
|
||||
<div>
|
||||
<label for="message" class="label">Message</label>
|
||||
<textarea id="message" name="message" rows="5" required
|
||||
class="input resize-none"
|
||||
placeholder="Tell us about your project..."></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-full py-3.5">
|
||||
<span class="htmx-indicator mr-2">
|
||||
<svg class="animate-spin h-4 w-4 inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
Send Message
|
||||
</button>
|
||||
</form>
|
||||
<div id="form-response" class="mt-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Info -->
|
||||
<div class="space-y-8">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Contact Information</h2>
|
||||
<p class="text-gray-600 mb-8">
|
||||
Feel free to reach out through the form or use any of the contact methods below.
|
||||
We typically respond within 24 hours.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-start">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
<div class="lg:col-span-2 flex flex-col gap-5">
|
||||
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
|
||||
style="background: rgba(92,184,44,0.12); border: 1px solid rgba(92,184,44,0.25);">
|
||||
<svg class="w-5 h-5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Email</h3>
|
||||
<p class="text-gray-600">hello@directlx.dev</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Location</h3>
|
||||
<p class="text-gray-600">Remote - Worldwide</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<h3 class="text-lg font-semibold text-gray-900">Response Time</h3>
|
||||
<p class="text-gray-600">Within 24 hours</p>
|
||||
<div>
|
||||
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Email</div>
|
||||
<div class="text-sm font-medium" style="color: #e8e6f0;">hello@directlx.dev</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Social Links -->
|
||||
<div class="pt-8 border-t border-gray-200">
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Follow Us</h3>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center text-gray-600 hover:bg-primary-100 hover:text-primary-600 transition-colors">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
|
||||
style="background: rgba(247,147,30,0.08); border: 1px solid rgba(247,147,30,0.2);">
|
||||
<svg class="w-5 h-5 text-accent-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Location</div>
|
||||
<div class="text-sm font-medium" style="color: #e8e6f0;">Remote — Worldwide</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
|
||||
style="background: rgba(92,184,44,0.12); border: 1px solid rgba(92,184,44,0.25);">
|
||||
<svg class="w-5 h-5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Response Time</div>
|
||||
<div class="text-sm font-medium" style="color: #e8e6f0;">Within 24 hours</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Social links -->
|
||||
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||
<div class="text-xs font-semibold tracking-wider uppercase mb-4" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Follow Us</div>
|
||||
<div class="flex gap-3">
|
||||
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||
style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); color: #8b8ca8;"
|
||||
onmouseover="this.style.borderColor='rgba(92,184,44,0.4)'; this.style.color='#86efac';"
|
||||
onmouseout="this.style.borderColor='rgba(255,255,255,0.08)'; this.style.color='#8b8ca8';">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center text-gray-600 hover:bg-primary-100 hover:text-primary-600 transition-colors">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||
style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); color: #8b8ca8;"
|
||||
onmouseover="this.style.borderColor='rgba(92,184,44,0.4)'; this.style.color='#86efac';"
|
||||
onmouseout="this.style.borderColor='rgba(255,255,255,0.08)'; this.style.color='#8b8ca8';">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center text-gray-600 hover:bg-primary-100 hover:text-primary-600 transition-colors">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||
style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); color: #8b8ca8;"
|
||||
onmouseover="this.style.borderColor='rgba(92,184,44,0.4)'; this.style.color='#86efac';"
|
||||
onmouseout="this.style.borderColor='rgba(255,255,255,0.08)'; this.style.color='#8b8ca8';">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
|
@ -139,4 +149,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,51 +3,61 @@
|
|||
{% block title %}{{ category.name }} - Forum{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Category Header -->
|
||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-12">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center text-sm text-gray-400 mb-4">
|
||||
<a href="{{ url_for('forum_index') }}" class="hover:text-white">← Back to Forum</a>
|
||||
<section class="relative py-20 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[500px] h-[300px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.09) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-5">
|
||||
<a href="{{ url_for('forum_index') }}" class="inline-flex items-center gap-2 text-sm font-medium text-primary-400 hover:text-primary-300 transition-colors">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16l-4-4m0 0l4-4m-4 4h18"/>
|
||||
</svg>
|
||||
Back to Forum
|
||||
</a>
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-4xl font-bold mb-2">{{ category.name }}</h1>
|
||||
<p class="text-gray-300">{{ category.description }}</p>
|
||||
<div class="badge badge-primary mb-4">Category</div>
|
||||
<h1 class="text-4xl md:text-5xl font-extrabold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
{{ category.name }}
|
||||
</h1>
|
||||
<p class="text-base" style="color: #8b8ca8;">{{ category.description }}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- New Topic Button & Topics List -->
|
||||
<section class="py-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center mb-8">
|
||||
<h2 class="text-xl font-bold text-gray-900">{{ topics.total if topics else 0 }} Topics</h2>
|
||||
<!-- Topics -->
|
||||
<section class="py-10 pb-24" style="background: #0a0a14;">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div class="text-xs font-semibold tracking-widest uppercase" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">
|
||||
{{ topics.total if topics else 0 }} Topics
|
||||
</div>
|
||||
<button onclick="document.getElementById('new-topic-modal').classList.remove('hidden')"
|
||||
class="btn btn-primary">
|
||||
<svg class="w-5 h-5 mr-2 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="btn btn-primary text-sm">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
New Topic
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Topics List -->
|
||||
<div id="topics-list">
|
||||
{% include "forum/partials/topic_list.html" %}
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if topics and topics.pages > 1 %}
|
||||
<div class="flex justify-center mt-8 space-x-2">
|
||||
<div class="flex justify-center mt-10 gap-2">
|
||||
{% if topics.has_prev %}
|
||||
<a href="{{ url_for('forum_category', slug=category.slug, page=topics.prev_num) }}" class="btn btn-secondary">
|
||||
<a href="{{ url_for('forum_category', slug=category.slug, page=topics.prev_num) }}" class="btn btn-outline">
|
||||
← Previous
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<span class="btn bg-gray-100 text-gray-600">
|
||||
Page {{ topics.page }} of {{ topics.pages }}
|
||||
</span>
|
||||
|
||||
<span class="btn btn-secondary">Page {{ topics.page }} of {{ topics.pages }}</span>
|
||||
{% if topics.has_next %}
|
||||
<a href="{{ url_for('forum_category', slug=category.slug, page=topics.next_num) }}" class="btn btn-secondary">
|
||||
<a href="{{ url_for('forum_category', slug=category.slug, page=topics.next_num) }}" class="btn btn-outline">
|
||||
Next →
|
||||
</a>
|
||||
{% endif %}
|
||||
|
|
@ -57,12 +67,15 @@
|
|||
</section>
|
||||
|
||||
<!-- New Topic Modal -->
|
||||
<div id="new-topic-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50 flex items-center justify-center">
|
||||
<div class="bg-white rounded-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
|
||||
<div class="p-6 border-b border-gray-200 flex justify-between items-center">
|
||||
<h3 class="text-xl font-bold text-gray-900">Create New Topic</h3>
|
||||
<button onclick="document.getElementById('new-topic-modal').classList.add('hidden')" class="text-gray-500 hover:text-gray-700">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<div id="new-topic-modal" class="fixed inset-0 hidden z-50 flex items-center justify-center p-4"
|
||||
style="background: rgba(0,0,0,0.7); backdrop-filter: blur(8px);">
|
||||
<div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-2xl"
|
||||
style="background: #0f0f1a; border: 1px solid rgba(92,184,44,0.3); box-shadow: 0 0 60px rgba(92,184,44,0.15);">
|
||||
<div class="flex justify-between items-center px-7 py-5" style="border-bottom: 1px solid rgba(255,255,255,0.06);">
|
||||
<h3 class="text-lg font-bold" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Create New Topic</h3>
|
||||
<button onclick="document.getElementById('new-topic-modal').classList.add('hidden')"
|
||||
class="w-8 h-8 rounded-lg flex items-center justify-center text-gray-500 hover:text-white hover:bg-white/10 transition-all">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
|
|
@ -71,42 +84,33 @@
|
|||
hx-target="#topics-list"
|
||||
hx-swap="innerHTML"
|
||||
hx-on::after-request="if(event.detail.successful) document.getElementById('new-topic-modal').classList.add('hidden')"
|
||||
class="p-6 space-y-4">
|
||||
class="p-7 space-y-5">
|
||||
<div>
|
||||
<label for="title" class="label">Topic Title</label>
|
||||
<input type="text" id="title" name="title" required class="input" placeholder="Enter a descriptive title">
|
||||
</div>
|
||||
<div>
|
||||
<label for="content" class="label">Content</label>
|
||||
<textarea id="content" name="content" rows="6" required class="input resize-none" placeholder="Share your thoughts, ask a question..."></textarea>
|
||||
<textarea id="content" name="content" rows="6" required class="input resize-none" placeholder="Share your thoughts, ask a question…"></textarea>
|
||||
</div>
|
||||
<div class="flex justify-end space-x-3">
|
||||
<button type="button" onclick="document.getElementById('new-topic-modal').classList.add('hidden')" class="btn btn-secondary">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Create Topic
|
||||
</button>
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
<button type="button" onclick="document.getElementById('new-topic-modal').classList.add('hidden')"
|
||||
class="btn btn-secondary">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Create Topic</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// Close modal on escape key
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.getElementById('new-topic-modal').classList.add('hidden');
|
||||
}
|
||||
if (e.key === 'Escape') document.getElementById('new-topic-modal').classList.add('hidden');
|
||||
});
|
||||
|
||||
// Close modal on backdrop click
|
||||
document.getElementById('new-topic-modal').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
this.classList.add('hidden');
|
||||
}
|
||||
if (e.target === this) this.classList.add('hidden');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,108 +3,123 @@
|
|||
{% block title %}Forum{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-4">Community Forum</h1>
|
||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
||||
Connect with other developers, ask questions, share knowledge, and grow together.
|
||||
</p>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="relative py-24 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[350px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="badge badge-accent mb-6">Community</div>
|
||||
<h1 class="text-5xl md:text-6xl font-extrabold mb-5 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Community <span class="gradient-text">Forum</span>
|
||||
</h1>
|
||||
<p class="text-lg max-w-xl mx-auto mb-10" style="color: #8b8ca8;">
|
||||
Connect with other developers, ask questions, share knowledge, and grow together.
|
||||
</p>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="max-w-md mx-auto relative">
|
||||
<input type="text"
|
||||
placeholder="Search topics…"
|
||||
class="input pl-11 py-3.5"
|
||||
hx-get="{{ url_for('forum_search') }}"
|
||||
hx-trigger="keyup changed delay:500ms"
|
||||
hx-target="#search-results"
|
||||
name="q">
|
||||
<svg class="w-4 h-4 absolute left-4 top-1/2 -translate-y-1/2 pointer-events-none" style="color: #6b6b8a;"
|
||||
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Forum Categories -->
|
||||
<section class="py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center mb-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900">Categories</h2>
|
||||
<div class="relative">
|
||||
<input type="text"
|
||||
placeholder="Search topics..."
|
||||
class="input pl-10"
|
||||
hx-get="{{ url_for('forum_search') }}"
|
||||
hx-trigger="keyup changed delay:500ms"
|
||||
hx-target="#search-results"
|
||||
name="q">
|
||||
<svg class="w-5 h-5 text-gray-400 absolute left-3 top-1/2 transform -translate-y-1/2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Categories -->
|
||||
<section class="py-16" style="background: #0a0a14;">
|
||||
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
||||
<!-- Search Results Container -->
|
||||
<div id="search-results" class="mb-8"></div>
|
||||
<!-- Search results -->
|
||||
<div id="search-results" class="mb-6"></div>
|
||||
|
||||
<!-- Categories -->
|
||||
<div class="mb-4 text-xs font-semibold tracking-widest uppercase" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Categories</div>
|
||||
|
||||
<!-- Categories List -->
|
||||
{% if categories %}
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-3">
|
||||
{% for category in categories %}
|
||||
<a href="{{ url_for('forum_category', slug=category.slug) }}" class="card block hover:shadow-lg transition-shadow group">
|
||||
<div class="flex items-start">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0 group-hover:bg-primary-200 transition-colors">
|
||||
<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-4 flex-grow">
|
||||
<h3 class="text-xl font-semibold text-gray-900 group-hover:text-primary-600 transition-colors">
|
||||
{{ category.name }}
|
||||
</h3>
|
||||
<p class="text-gray-600 mt-1">{{ category.description }}</p>
|
||||
</div>
|
||||
<div class="text-right text-sm text-gray-500">
|
||||
<div>{{ category.topics.count() }} topics</div>
|
||||
</div>
|
||||
<a href="{{ url_for('forum_category', slug=category.slug) }}"
|
||||
class="card-hover flex items-center gap-5 p-6 group block">
|
||||
<div class="w-11 h-11 rounded-xl flex items-center justify-center flex-shrink-0"
|
||||
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||
<svg class="w-5 h-5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-grow min-w-0">
|
||||
<h3 class="text-base font-bold mb-0.5 group-hover:text-primary-300 transition-colors" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
{{ category.name }}
|
||||
</h3>
|
||||
<p class="text-sm truncate" style="color: #8b8ca8;">{{ category.description }}</p>
|
||||
</div>
|
||||
<div class="flex-shrink-0 text-right">
|
||||
<div class="text-sm font-semibold" style="color: #e8e6f0;">{{ category.topics.count() }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">topics</div>
|
||||
</div>
|
||||
<svg class="w-4 h-4 flex-shrink-0 text-primary-500 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-16">
|
||||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" />
|
||||
<div class="w-14 h-14 rounded-xl flex items-center justify-center mx-auto mb-4"
|
||||
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||
<svg class="w-7 h-7 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No categories yet</h3>
|
||||
<p class="text-gray-600">The forum is being set up. Check back soon!</p>
|
||||
<h3 class="text-lg font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No categories yet</h3>
|
||||
<p class="text-sm" style="color: #6b6b8a;">The forum is being set up. Check back soon!</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Recent Activity -->
|
||||
<section class="bg-gray-100 py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-8">Recent Activity</h2>
|
||||
<section class="py-16 relative">
|
||||
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||
<div class="relative max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-6 text-xs font-semibold tracking-widest uppercase" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Recent Activity</div>
|
||||
|
||||
{% if recent_topics %}
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-3">
|
||||
{% for topic in recent_topics %}
|
||||
<div class="card flex items-center">
|
||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold mr-4">
|
||||
{{ topic.author.username[0].upper() }}
|
||||
</div>
|
||||
<div class="flex-grow">
|
||||
<a href="{{ url_for('forum_topic', category_slug=topic.category.slug, topic_id=topic.id) }}" class="font-medium text-gray-900 hover:text-primary-600">
|
||||
<div class="card flex items-center gap-4 p-5" style="border: 1px solid rgba(255,255,255,0.05);">
|
||||
<div class="avatar w-9 h-9 text-xs font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||
<div class="flex-grow min-w-0">
|
||||
<a href="{{ url_for('forum_topic', category_slug=topic.category.slug, topic_id=topic.id) }}"
|
||||
class="text-sm font-semibold text-gray-200 hover:text-primary-300 transition-colors truncate block">
|
||||
{{ topic.title }}
|
||||
</a>
|
||||
<div class="text-sm text-gray-500">
|
||||
<div class="text-xs mt-0.5" style="color: #6b6b8a;">
|
||||
by {{ topic.author.username }} in
|
||||
<a href="{{ url_for('forum_category', slug=topic.category.slug) }}" class="text-primary-600 hover:underline">{{ topic.category.name }}</a>
|
||||
<a href="{{ url_for('forum_category', slug=topic.category.slug) }}" class="text-primary-500 hover:text-primary-400">{{ topic.category.name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ topic.reply_count }} replies
|
||||
<div class="flex-shrink-0 text-right">
|
||||
<div class="text-xs font-semibold" style="color: #e8e6f0;">{{ topic.reply_count }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">replies</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-gray-600 text-center py-8">No recent activity yet.</p>
|
||||
<p class="text-sm text-center py-10" style="color: #6b6b8a;">No recent activity yet.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="card">
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Add a Reply</h3>
|
||||
<div class="card p-7" style="border: 1px solid rgba(92,184,44,0.2);">
|
||||
<h3 class="text-base font-bold mb-5" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Add a Reply</h3>
|
||||
<form hx-post="{{ url_for('forum_add_reply', category_slug=topic.category.slug, topic_id=topic.id) }}"
|
||||
hx-target="#replies-list"
|
||||
hx-swap="beforeend"
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<div class="mb-4">
|
||||
<textarea name="content" rows="4" required
|
||||
class="input resize-none"
|
||||
placeholder="Write your reply..."></textarea>
|
||||
placeholder="Write your reply…"></textarea>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
|
|
|
|||
|
|
@ -1,43 +1,43 @@
|
|||
{% if topics and topics.items %}
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-3">
|
||||
{% for topic in topics.items %}
|
||||
<div class="card hover:shadow-lg transition-shadow {% if topic.is_pinned %}border-l-4 border-primary-500{% endif %}">
|
||||
<div class="flex items-start">
|
||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold flex-shrink-0">
|
||||
{{ topic.author.username[0].upper() }}
|
||||
<div class="card flex items-center gap-4 p-5 transition-all duration-300 group
|
||||
{% if topic.is_pinned %}{% else %}{% endif %}"
|
||||
style="border: 1px solid {% if topic.is_pinned %}rgba(92,184,44,0.3){% else %}rgba(255,255,255,0.05){% endif %};">
|
||||
<div class="avatar w-10 h-10 text-sm font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||
<div class="flex-grow min-w-0">
|
||||
<div class="flex items-center gap-2 mb-1 flex-wrap">
|
||||
{% if topic.is_pinned %}
|
||||
<span class="badge badge-primary text-xs">Pinned</span>
|
||||
{% endif %}
|
||||
{% if topic.is_locked %}
|
||||
<span class="badge badge-red text-xs">Locked</span>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('forum_topic', category_slug=category.slug, topic_id=topic.id) }}"
|
||||
class="text-sm font-semibold text-gray-200 hover:text-primary-300 transition-colors truncate">
|
||||
{{ topic.title }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-4 flex-grow">
|
||||
<div class="flex items-center mb-1">
|
||||
{% if topic.is_pinned %}
|
||||
<span class="bg-primary-100 text-primary-600 text-xs px-2 py-0.5 rounded mr-2">Pinned</span>
|
||||
{% endif %}
|
||||
{% if topic.is_locked %}
|
||||
<span class="bg-red-100 text-red-600 text-xs px-2 py-0.5 rounded mr-2">Locked</span>
|
||||
{% endif %}
|
||||
<a href="{{ url_for('forum_topic', category_slug=category.slug, topic_id=topic.id) }}" class="text-lg font-semibold text-gray-900 hover:text-primary-600 transition-colors">
|
||||
{{ topic.title }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
by {{ topic.author.username }} · {{ topic.created_at.strftime('%B %d, %Y') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right text-sm text-gray-500 flex-shrink-0">
|
||||
<div class="font-medium">{{ topic.reply_count }} replies</div>
|
||||
<div>Last activity: {{ topic.last_activity.strftime('%b %d') }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">
|
||||
by {{ topic.author.username }} · {{ topic.created_at.strftime('%b %d, %Y') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right flex-shrink-0">
|
||||
<div class="text-sm font-semibold" style="color: #e8e6f0;">{{ topic.reply_count }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">{{ topic.last_activity.strftime('%b %d') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-16">
|
||||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
||||
<div class="w-14 h-14 rounded-xl flex items-center justify-center mx-auto mb-4"
|
||||
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||
<svg class="w-7 h-7 text-primary-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No topics yet</h3>
|
||||
<p class="text-gray-600">Be the first to start a discussion!</p>
|
||||
<h3 class="text-lg font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No topics yet</h3>
|
||||
<p class="text-sm" style="color: #6b6b8a;">Be the first to start a discussion!</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -3,55 +3,55 @@
|
|||
{% block title %}{{ topic.title }} - Forum{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Topic Header -->
|
||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center text-sm text-gray-400 mb-4">
|
||||
<a href="{{ url_for('forum_index') }}" class="hover:text-white">Forum</a>
|
||||
<span class="mx-2">/</span>
|
||||
<a href="{{ url_for('forum_category', slug=topic.category.slug) }}" class="hover:text-white">{{ topic.category.name }}</a>
|
||||
<section class="relative py-16 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-25 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[500px] h-[250px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.08) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<!-- Breadcrumb -->
|
||||
<div class="flex items-center gap-2 text-sm mb-6" style="color: #6b6b8a;">
|
||||
<a href="{{ url_for('forum_index') }}" class="hover:text-primary-400 transition-colors">Forum</a>
|
||||
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
<a href="{{ url_for('forum_category', slug=topic.category.slug) }}" class="hover:text-primary-400 transition-colors">{{ topic.category.name }}</a>
|
||||
</div>
|
||||
<div class="flex items-start justify-between">
|
||||
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">
|
||||
{% if topic.is_pinned %}
|
||||
<svg class="w-5 h-5 inline mr-2 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M5 5a2 2 0 012-2h6a2 2 0 012 2v2a2 2 0 01-2 2H7a2 2 0 01-2-2V5z"/>
|
||||
<path d="M8 12a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z"/>
|
||||
<path fill-rule="evenodd" d="M10 18a1 1 0 01-1-1v-4a1 1 0 112 0v4a1 1 0 01-1 1z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
<div class="flex items-center gap-2 mb-3 flex-wrap">
|
||||
{% if topic.is_pinned %}<span class="badge badge-primary">Pinned</span>{% endif %}
|
||||
{% if topic.is_locked %}<span class="badge badge-red">Locked</span>{% endif %}
|
||||
</div>
|
||||
<h1 class="text-3xl md:text-4xl font-extrabold leading-tight mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
{{ topic.title }}
|
||||
{% if topic.is_locked %}
|
||||
<svg class="w-5 h-5 inline ml-2 text-red-400" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
{% endif %}
|
||||
</h1>
|
||||
<div class="text-gray-400 text-sm">
|
||||
Started by {{ topic.author.username }} · {{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}
|
||||
<div class="text-sm" style="color: #6b6b8a;">
|
||||
Started by <span style="color: #c4c2d4;">{{ topic.author.username }}</span>
|
||||
· {{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Original Post -->
|
||||
<section class="py-8">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="card mb-6">
|
||||
<div class="flex items-start">
|
||||
<div class="w-12 h-12 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold flex-shrink-0">
|
||||
{{ topic.author.username[0].upper() }}
|
||||
</div>
|
||||
<div class="ml-4 flex-grow">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="font-medium text-gray-900">{{ topic.author.username }}</div>
|
||||
<div class="text-sm text-gray-500">{{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
||||
</div>
|
||||
<div class="prose prose-sm max-w-none text-gray-600">
|
||||
{{ topic.content | safe }}
|
||||
<!-- Posts & Replies -->
|
||||
<section class="pb-24" style="background: #0a0a14;">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
|
||||
<!-- Original post -->
|
||||
<div class="card p-7 mb-4" style="border: 1px solid rgba(92,184,44,0.2);">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="avatar w-11 h-11 text-sm font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||
<div class="flex-grow min-w-0">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="font-semibold text-sm" style="color: #e8e6f0;">{{ topic.author.username }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">{{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
||||
</div>
|
||||
<div class="prose-dark text-sm leading-relaxed">{{ topic.content | safe }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,21 +59,19 @@
|
|||
<!-- Replies -->
|
||||
<div id="replies-list">
|
||||
{% if replies %}
|
||||
<h2 class="text-lg font-semibold text-gray-900 mb-4">{{ replies|length }} Replies</h2>
|
||||
<div class="text-xs font-semibold tracking-widest uppercase mt-10 mb-4" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">
|
||||
{{ replies|length }} {{ 'Reply' if replies|length == 1 else 'Replies' }}
|
||||
</div>
|
||||
{% for reply in replies %}
|
||||
<div class="card mb-4">
|
||||
<div class="flex items-start">
|
||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center text-gray-600 font-semibold flex-shrink-0">
|
||||
{{ reply.author.username[0].upper() }}
|
||||
</div>
|
||||
<div class="ml-4 flex-grow">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="font-medium text-gray-900">{{ reply.author.username }}</div>
|
||||
<div class="text-sm text-gray-500">{{ reply.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
||||
</div>
|
||||
<div class="prose prose-sm max-w-none text-gray-600">
|
||||
{{ reply.content | safe }}
|
||||
<div class="card p-6 mb-3" style="border: 1px solid rgba(255,255,255,0.05);">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="avatar w-9 h-9 text-xs font-bold flex-shrink-0">{{ reply.author.username[0].upper() }}</div>
|
||||
<div class="flex-grow min-w-0">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="font-semibold text-sm" style="color: #e8e6f0;">{{ reply.author.username }}</div>
|
||||
<div class="text-xs" style="color: #6b6b8a;">{{ reply.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
||||
</div>
|
||||
<div class="prose-dark text-sm leading-relaxed">{{ reply.content | safe }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -81,19 +79,20 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Reply Form -->
|
||||
<!-- Reply form or locked message -->
|
||||
{% if not topic.is_locked %}
|
||||
<div id="reply-form-container" class="mt-8">
|
||||
<div id="reply-form-container" class="mt-10">
|
||||
{% include "forum/partials/reply_form.html" %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card text-center py-8 text-gray-500">
|
||||
<svg class="w-12 h-12 mx-auto mb-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
<div class="card text-center py-10 mt-10" style="border: 1px solid rgba(239,68,68,0.2); background: rgba(239,68,68,0.05);">
|
||||
<svg class="w-10 h-10 mx-auto mb-3 text-red-500 opacity-60" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
<p>This topic is locked. No new replies can be added.</p>
|
||||
<p class="text-sm" style="color: #8b8ca8;">This topic is locked. No new replies can be added.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,134 +3,178 @@
|
|||
{% block title %}Home{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-primary-600 to-primary-800 text-white">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-6xl font-bold mb-6">
|
||||
Build Better Software,<br>
|
||||
<span class="text-accent-400">Faster</span>
|
||||
</h1>
|
||||
<p class="text-xl text-primary-100 max-w-2xl mx-auto mb-8">
|
||||
We help businesses transform their ideas into powerful, scalable software solutions.
|
||||
From concept to deployment, we're your trusted development partner.
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('contact') }}" class="btn bg-accent-500 text-white hover:bg-accent-600 px-8 py-3 text-lg">
|
||||
Get Started
|
||||
</a>
|
||||
<a href="{{ url_for('services') }}" class="btn border-2 border-white text-white hover:bg-white hover:text-primary-600 px-8 py-3 text-lg">
|
||||
Our Services
|
||||
</a>
|
||||
<section class="relative overflow-hidden" style="min-height: 88vh; display: flex; align-items: center;">
|
||||
<!-- Background glow orbs -->
|
||||
<div class="absolute inset-0 pointer-events-none">
|
||||
<div class="absolute top-[-100px] left-1/2 -translate-x-1/2 w-[700px] h-[500px] rounded-full"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.12) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
<div class="absolute bottom-[-50px] right-[-100px] w-[400px] h-[400px] rounded-full"
|
||||
style="background: radial-gradient(ellipse, rgba(247,147,30,0.06) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
<div class="absolute top-1/3 left-[-50px] w-[300px] h-[300px] rounded-full"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.07) 0%, transparent 70%); filter: blur(30px);"></div>
|
||||
</div>
|
||||
<!-- Dot grid -->
|
||||
<div class="absolute inset-0 dot-grid opacity-40 pointer-events-none"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24 text-center">
|
||||
<!-- Pre-heading badge -->
|
||||
<div class="inline-flex items-center gap-2 badge badge-primary mb-8">
|
||||
<svg class="w-3 h-3 text-primary-400" fill="currentColor" viewBox="0 0 8 8">
|
||||
<circle cx="4" cy="4" r="3"/>
|
||||
</svg>
|
||||
Software Engineering & Consulting
|
||||
</div>
|
||||
|
||||
<h1 class="font-display text-5xl md:text-7xl font-extrabold leading-[1.05] tracking-tight mb-7"
|
||||
style="font-family: 'Syne', sans-serif;">
|
||||
Build Better Software,<br>
|
||||
<span class="gradient-text">Faster.</span>
|
||||
</h1>
|
||||
|
||||
<p class="text-lg md:text-xl max-w-2xl mx-auto mb-10" style="color: #8b8ca8; line-height: 1.7;">
|
||||
We transform ideas into powerful, scalable software.
|
||||
From concept to deployment — your trusted development partner.
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary px-8 py-3.5 text-base">
|
||||
Get Started
|
||||
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="{{ url_for('services') }}" class="btn btn-outline px-8 py-3.5 text-base">
|
||||
Our Services
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Social proof strip -->
|
||||
<div class="mt-16 flex flex-wrap items-center justify-center gap-x-10 gap-y-4">
|
||||
<div class="text-center">
|
||||
<div class="text-3xl font-bold gradient-text-violet" style="font-family: 'Syne', sans-serif;">50+</div>
|
||||
<div class="text-xs mt-1" style="color: #6b6b8a;">Projects Shipped</div>
|
||||
</div>
|
||||
<div class="w-px h-8 hidden sm:block" style="background: rgba(255,255,255,0.08);"></div>
|
||||
<div class="text-center">
|
||||
<div class="text-3xl font-bold gradient-text-violet" style="font-family: 'Syne', sans-serif;">30+</div>
|
||||
<div class="text-xs mt-1" style="color: #6b6b8a;">Happy Clients</div>
|
||||
</div>
|
||||
<div class="w-px h-8 hidden sm:block" style="background: rgba(255,255,255,0.08);"></div>
|
||||
<div class="text-center">
|
||||
<div class="text-3xl font-bold gradient-text-violet" style="font-family: 'Syne', sans-serif;">5+</div>
|
||||
<div class="text-xs mt-1" style="color: #6b6b8a;">Years Experience</div>
|
||||
</div>
|
||||
<div class="w-px h-8 hidden sm:block" style="background: rgba(255,255,255,0.08);"></div>
|
||||
<div class="text-center">
|
||||
<div class="text-3xl font-bold gradient-text-violet" style="font-family: 'Syne', sans-serif;">99%</div>
|
||||
<div class="text-xs mt-1" style="color: #6b6b8a;">Satisfaction Rate</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section class="py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<section class="py-24 relative">
|
||||
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Why Choose DirectLX?</h2>
|
||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
||||
We combine technical expertise with a deep understanding of business needs
|
||||
to deliver solutions that truly make a difference.
|
||||
<div class="badge badge-primary mb-5">Why DirectLX</div>
|
||||
<h2 class="text-3xl md:text-4xl font-bold mb-4" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Engineering excellence,<br><span class="gradient-text">by design</span>
|
||||
</h2>
|
||||
<p class="max-w-xl mx-auto text-base" style="color: #8b8ca8;">
|
||||
We combine deep technical expertise with a genuine understanding of business needs to deliver solutions that make a real difference.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<!-- Card 1 -->
|
||||
<div class="card-hover group p-8">
|
||||
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||
style="background: rgba(92,184,44,0.12); border: 1px solid rgba(92,184,44,0.25);">
|
||||
<svg class="w-6 h-6 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Fast Delivery</h3>
|
||||
<p class="text-gray-600">
|
||||
Agile methodology and modern tools ensure rapid development without compromising quality.
|
||||
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Fast Delivery</h3>
|
||||
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||
Agile methodology and modern tooling ensure rapid iteration without sacrificing quality or reliability.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||
<!-- Card 2 -->
|
||||
<div class="card-hover group p-8">
|
||||
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||
style="background: rgba(247,147,30,0.08); border: 1px solid rgba(247,147,30,0.2);">
|
||||
<svg class="w-6 h-6 text-accent-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Secure & Reliable</h3>
|
||||
<p class="text-gray-600">
|
||||
Security-first approach with industry best practices and thorough testing.
|
||||
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Secure & Reliable</h3>
|
||||
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||
Security-first architecture with industry best practices and thorough testing at every stage.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
<!-- Card 3 -->
|
||||
<div class="card-hover group p-8">
|
||||
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||
style="background: rgba(92,184,44,0.12); border: 1px solid rgba(92,184,44,0.25);">
|
||||
<svg class="w-6 h-6 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Expert Team</h3>
|
||||
<p class="text-gray-600">
|
||||
Experienced developers passionate about creating exceptional software solutions.
|
||||
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Expert Team</h3>
|
||||
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||
Seasoned engineers passionate about clean code, scalable architecture, and exceptional outcomes.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Stats Section -->
|
||||
<section class="bg-gray-900 text-white py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
|
||||
<div>
|
||||
<div class="text-4xl font-bold text-accent-400 mb-2">50+</div>
|
||||
<div class="text-gray-400">Projects Delivered</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-4xl font-bold text-accent-400 mb-2">30+</div>
|
||||
<div class="text-gray-400">Happy Clients</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-4xl font-bold text-accent-400 mb-2">5+</div>
|
||||
<div class="text-gray-400">Years Experience</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-4xl font-bold text-accent-400 mb-2">99%</div>
|
||||
<div class="text-gray-400">Client Satisfaction</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Latest Blog Posts -->
|
||||
<section class="py-20">
|
||||
<section class="py-24" style="background: #0a0a14;">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center mb-12">
|
||||
<h2 class="text-3xl font-bold text-gray-900">Latest from the Blog</h2>
|
||||
<a href="{{ url_for('blog_index') }}" class="text-primary-600 hover:text-primary-700 font-medium">
|
||||
View all posts →
|
||||
<div class="flex justify-between items-end mb-12">
|
||||
<div>
|
||||
<div class="badge badge-primary mb-4">From the Blog</div>
|
||||
<h2 class="text-3xl font-bold" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Latest insights</h2>
|
||||
</div>
|
||||
<a href="{{ url_for('blog_index') }}" class="text-sm font-medium text-primary-400 hover:text-primary-300 transition-colors hidden sm:flex items-center gap-1">
|
||||
All posts
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{% if latest_posts %}
|
||||
{% for post in latest_posts %}
|
||||
<article class="card hover:shadow-lg transition-shadow">
|
||||
<div class="text-sm text-gray-500 mb-2">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="hover:text-primary-600">
|
||||
<article class="card-hover group flex flex-col p-7">
|
||||
<div class="text-xs mb-4 font-medium tracking-wide" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||
<h3 class="text-lg font-bold mb-3 leading-snug" style="font-family: 'Syne', sans-serif;">
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-gray-100 hover:text-primary-300 transition-colors">
|
||||
{{ post.title }}
|
||||
</a>
|
||||
</h3>
|
||||
<p class="text-gray-600 mb-4">{{ post.excerpt or post.content[:150] }}...</p>
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-primary-600 hover:text-primary-700 font-medium">
|
||||
Read more →
|
||||
<p class="text-sm leading-relaxed mb-6 flex-grow" style="color: #8b8ca8;">
|
||||
{{ post.excerpt or post.content[:140] }}…
|
||||
</p>
|
||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-sm font-semibold text-primary-400 hover:text-primary-300 flex items-center gap-1 transition-colors">
|
||||
Read more
|
||||
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="col-span-3 text-center text-gray-500 py-8">
|
||||
<p>No blog posts yet. Check back soon!</p>
|
||||
<div class="col-span-3 text-center py-12" style="color: #6b6b8a;">
|
||||
<p>No posts yet — check back soon.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
@ -138,16 +182,31 @@
|
|||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="bg-primary-600 text-white py-16">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4">Ready to Start Your Project?</h2>
|
||||
<p class="text-primary-100 max-w-2xl mx-auto mb-8">
|
||||
Let's discuss how we can help bring your vision to life.
|
||||
Get in touch for a free consultation.
|
||||
</p>
|
||||
<a href="{{ url_for('contact') }}" class="btn bg-white text-primary-600 hover:bg-gray-100 px-8 py-3 text-lg">
|
||||
Contact Us Today
|
||||
</a>
|
||||
<section class="py-24 relative overflow-hidden">
|
||||
<div class="absolute inset-0 pointer-events-none">
|
||||
<div class="absolute inset-0 dot-grid opacity-30"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[300px]"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.15) 0%, transparent 70%); filter: blur(30px);"></div>
|
||||
</div>
|
||||
<div class="relative max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="inline-block p-px rounded-2xl mb-10"
|
||||
style="background: linear-gradient(135deg, rgba(92,184,44,0.4), rgba(247,147,30,0.2));">
|
||||
<div class="rounded-2xl px-10 py-12" style="background: #0f0f1a;">
|
||||
<h2 class="text-3xl md:text-4xl font-bold mb-4" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Ready to start<br><span class="gradient-text">your project?</span>
|
||||
</h2>
|
||||
<p class="text-base mb-8" style="color: #8b8ca8;">
|
||||
Let's discuss how we can help bring your vision to life. Free consultation, no strings attached.
|
||||
</p>
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary px-10 py-3.5 text-base">
|
||||
Get in Touch
|
||||
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -3,216 +3,137 @@
|
|||
{% block title %}Services{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<section class="bg-gradient-to-br from-primary-600 to-primary-800 text-white py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">Our Services</h1>
|
||||
<p class="text-xl text-primary-100 max-w-2xl mx-auto">
|
||||
Comprehensive software solutions tailored to your business needs.
|
||||
From development to deployment, we've got you covered.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="relative py-28 overflow-hidden">
|
||||
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[700px] h-[400px] pointer-events-none"
|
||||
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div class="badge badge-primary mb-6">What We Do</div>
|
||||
<h1 class="text-5xl md:text-6xl font-extrabold mb-6 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Our <span class="gradient-text">Services</span>
|
||||
</h1>
|
||||
<p class="text-lg max-w-2xl mx-auto" style="color: #8b8ca8;">
|
||||
Comprehensive software solutions tailored to your business needs — from development to deployment.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Services Grid -->
|
||||
<section class="py-20">
|
||||
<section class="py-20" style="background: #0a0a14;">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<!-- Web Development -->
|
||||
<div class="card hover:shadow-lg transition-shadow">
|
||||
<div class="w-14 h-14 bg-primary-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-2xl font-semibold text-gray-900 mb-3">Web Development</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Modern, responsive websites and web applications built with the latest technologies.
|
||||
From simple landing pages to complex enterprise platforms.
|
||||
</p>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Custom web applications
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
E-commerce solutions
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Progressive Web Apps (PWAs)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
|
||||
<!-- API Development -->
|
||||
<div class="card hover:shadow-lg transition-shadow">
|
||||
<div class="w-14 h-14 bg-primary-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-2xl font-semibold text-gray-900 mb-3">API Development</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Robust, scalable APIs that power your applications and enable seamless integrations
|
||||
with third-party services.
|
||||
</p>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
RESTful API design
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
GraphQL implementations
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Third-party integrations
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% set services = [
|
||||
{
|
||||
'icon': 'M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9',
|
||||
'title': 'Web Development',
|
||||
'desc': 'Modern, responsive websites and web applications built with the latest technologies. From simple landing pages to complex enterprise platforms.',
|
||||
'items': ['Custom web applications', 'E-commerce solutions', 'Progressive Web Apps (PWAs)'],
|
||||
'accent': 'primary'
|
||||
},
|
||||
{
|
||||
'icon': 'M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z',
|
||||
'title': 'API Development',
|
||||
'desc': 'Robust, scalable APIs that power your applications and enable seamless integrations with third-party services.',
|
||||
'items': ['RESTful API design', 'GraphQL implementations', 'Third-party integrations'],
|
||||
'accent': 'accent'
|
||||
},
|
||||
{
|
||||
'icon': 'M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z',
|
||||
'title': 'Cloud Solutions',
|
||||
'desc': 'Leverage the power of cloud computing with our expertise in AWS, Azure, and Google Cloud Platform.',
|
||||
'items': ['Cloud architecture design', 'Migration services', 'DevOps & CI/CD pipelines'],
|
||||
'accent': 'accent'
|
||||
},
|
||||
{
|
||||
'icon': 'M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z',
|
||||
'title': 'Technical Consulting',
|
||||
'desc': 'Expert guidance on technology strategy, architecture decisions, and best practices for your development team.',
|
||||
'items': ['Technology assessment', 'Code reviews & audits', 'Team training'],
|
||||
'accent': 'primary'
|
||||
},
|
||||
] %}
|
||||
|
||||
<!-- Cloud Solutions -->
|
||||
<div class="card hover:shadow-lg transition-shadow">
|
||||
<div class="w-14 h-14 bg-primary-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" />
|
||||
{% for svc in services %}
|
||||
<div class="card-hover p-8">
|
||||
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6 flex-shrink-0"
|
||||
style="background: rgba({% if svc.accent == 'accent' %}34,211,238{% else %}124,58,237{% endif %},0.1); border: 1px solid rgba({% if svc.accent == 'accent' %}34,211,238{% else %}124,58,237{% endif %},0.25);">
|
||||
<svg class="w-6 h-6 {% if svc.accent == 'accent' %}text-accent-400{% else %}text-primary-400{% endif %}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="{{ svc.icon }}" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-2xl font-semibold text-gray-900 mb-3">Cloud Solutions</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Leverage the power of cloud computing with our expertise in AWS, Azure, and
|
||||
Google Cloud Platform.
|
||||
</p>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Cloud architecture design
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Migration services
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
DevOps & CI/CD pipelines
|
||||
<h3 class="text-xl font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">{{ svc.title }}</h3>
|
||||
<p class="text-sm leading-relaxed mb-6" style="color: #8b8ca8;">{{ svc.desc }}</p>
|
||||
<ul class="space-y-2.5">
|
||||
{% for item in svc.items %}
|
||||
<li class="flex items-center gap-3 text-sm" style="color: #c4c2d4;">
|
||||
<div class="w-1.5 h-1.5 rounded-full flex-shrink-0 {% if svc.accent == 'accent' %}bg-accent-400{% else %}bg-primary-400{% endif %}"></div>
|
||||
{{ item }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<!-- Consulting -->
|
||||
<div class="card hover:shadow-lg transition-shadow">
|
||||
<div class="w-14 h-14 bg-primary-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-2xl font-semibold text-gray-900 mb-3">Technical Consulting</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Expert guidance on technology strategy, architecture decisions, and best practices
|
||||
for your development team.
|
||||
</p>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Technology assessment
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Code reviews & audits
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
Team training
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Process Section -->
|
||||
<section class="bg-gray-100 py-20">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<!-- Process -->
|
||||
<section class="py-24 relative">
|
||||
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="text-center mb-16">
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Our Process</h2>
|
||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
||||
A structured approach that ensures quality delivery and client satisfaction.
|
||||
</p>
|
||||
<div class="badge badge-primary mb-5">How We Work</div>
|
||||
<h2 class="text-3xl font-bold" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
A process built for<br><span class="gradient-text">results</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<div class="text-center">
|
||||
<div class="w-16 h-16 bg-accent-500 text-white rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">
|
||||
1
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 relative">
|
||||
<!-- Connector line -->
|
||||
<div class="hidden md:block absolute top-9 left-[12.5%] right-[12.5%] h-px"
|
||||
style="background: linear-gradient(90deg, rgba(92,184,44,0.5), rgba(247,147,30,0.5));"></div>
|
||||
|
||||
{% set steps = [
|
||||
('01', 'Discovery', 'Understanding your requirements, goals, and challenges.'),
|
||||
('02', 'Planning', 'Designing the architecture and creating a detailed roadmap.'),
|
||||
('03', 'Development', 'Building your solution with regular updates and feedback cycles.'),
|
||||
('04', 'Delivery', 'Testing, deployment, and ongoing support.'),
|
||||
] %}
|
||||
{% for num, title, desc in steps %}
|
||||
<div class="text-center relative">
|
||||
<div class="w-[72px] h-[72px] mx-auto mb-5 rounded-xl flex items-center justify-center relative z-10"
|
||||
style="background: #0f0f1a; border: 1px solid rgba(92,184,44,0.4); box-shadow: 0 0 20px rgba(92,184,44,0.12);">
|
||||
<span class="text-xl font-extrabold gradient-text" style="font-family: 'Syne', sans-serif;">{{ num }}</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Discovery</h3>
|
||||
<p class="text-gray-600">Understanding your requirements, goals, and challenges.</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="w-16 h-16 bg-accent-500 text-white rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">
|
||||
2
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Planning</h3>
|
||||
<p class="text-gray-600">Designing the architecture and creating a detailed roadmap.</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="w-16 h-16 bg-accent-500 text-white rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">
|
||||
3
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Development</h3>
|
||||
<p class="text-gray-600">Building your solution with regular updates and feedback cycles.</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="w-16 h-16 bg-accent-500 text-white rounded-full flex items-center justify-center mx-auto mb-4 text-2xl font-bold">
|
||||
4
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Delivery</h3>
|
||||
<p class="text-gray-600">Testing, deployment, and ongoing support.</p>
|
||||
<h3 class="text-base font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">{{ title }}</h3>
|
||||
<p class="text-sm" style="color: #8b8ca8;">{{ desc }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="py-20">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Ready to Get Started?</h2>
|
||||
<p class="text-gray-600 mb-8 max-w-2xl mx-auto">
|
||||
Whether you have a specific project in mind or need help defining your requirements,
|
||||
we're here to help. Let's discuss how we can work together.
|
||||
<!-- CTA -->
|
||||
<section class="py-20" style="background: #0a0a14;">
|
||||
<div class="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||
Ready to get <span class="gradient-text">started?</span>
|
||||
</h2>
|
||||
<p class="text-base mb-8" style="color: #8b8ca8;">
|
||||
Whether you have a specific project in mind or need help defining your requirements, we're here to help.
|
||||
</p>
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-accent px-8 py-3 text-lg">
|
||||
<a href="{{ url_for('contact') }}" class="btn btn-primary px-10 py-3.5 text-base">
|
||||
Request a Consultation
|
||||
<svg class="w-4 h-4 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue