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 components;
|
||||||
@tailwind utilities;
|
@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 {
|
@layer components {
|
||||||
|
/* Buttons */
|
||||||
.btn {
|
.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 {
|
.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 {
|
.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 {
|
.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 {
|
.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 {
|
.btn-ghost {
|
||||||
@apply border-2 border-accent-500 text-accent-500 hover:bg-accent-500 hover:text-white;
|
@apply text-gray-400 hover:text-white hover:bg-white/5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cards */
|
||||||
.card {
|
.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 {
|
.card-hover {
|
||||||
@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;
|
@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 {
|
.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 {
|
.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 {
|
/* Gradient text */
|
||||||
@apply text-primary-600 font-semibold;
|
.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;
|
opacity: 0;
|
||||||
transition: opacity 200ms ease-in;
|
transition: opacity 200ms ease-in;
|
||||||
}
|
}
|
||||||
|
.htmx-request .htmx-indicator { opacity: 1; }
|
||||||
|
.htmx-request.htmx-indicator { opacity: 1; }
|
||||||
|
|
||||||
.htmx-request .htmx-indicator {
|
/* Prose overrides for dark theme */
|
||||||
opacity: 1;
|
.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 {
|
/* Animations */
|
||||||
opacity: 1;
|
@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,6 +6,10 @@ module.exports = {
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
display: ['Syne', 'sans-serif'],
|
||||||
|
body: ['DM Sans', 'sans-serif'],
|
||||||
|
},
|
||||||
colors: {
|
colors: {
|
||||||
primary: {
|
primary: {
|
||||||
50: '#f0fdf4',
|
50: '#f0fdf4',
|
||||||
|
|
@ -30,8 +34,21 @@ module.exports = {
|
||||||
700: '#c2640a',
|
700: '#c2640a',
|
||||||
800: '#9a4f0d',
|
800: '#9a4f0d',
|
||||||
900: '#7c400e',
|
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: [],
|
plugins: [],
|
||||||
|
|
|
||||||
|
|
@ -3,103 +3,88 @@
|
||||||
{% block title %}About Us{% endblock %}
|
{% block title %}About Us{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Hero Section -->
|
|
||||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-20">
|
<!-- Hero -->
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<section class="relative py-28 overflow-hidden">
|
||||||
<div class="text-center">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">About DirectLX</h1>
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] pointer-events-none"
|
||||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||||
We're a team of passionate developers dedicated to building software that makes a difference.
|
|
||||||
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Our Story -->
|
<!-- Story + Values -->
|
||||||
<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="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>
|
<div>
|
||||||
<h2 class="text-3xl font-bold text-gray-900 mb-6">Our Story</h2>
|
<h2 class="text-3xl font-bold mb-6" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Our Story</h2>
|
||||||
<p class="text-gray-600 mb-4">
|
<div class="space-y-4 text-base leading-relaxed" style="color: #8b8ca8;">
|
||||||
DirectLX was founded with a simple mission: to help businesses succeed through technology.
|
<p>
|
||||||
We believe that great software isn't just about code—it's about understanding problems
|
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.
|
||||||
and crafting solutions that truly work.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-gray-600 mb-4">
|
<p>
|
||||||
Over the years, we've had the privilege of working with startups, growing businesses,
|
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.
|
||||||
and established enterprises across various industries. Each project has taught us
|
|
||||||
something new and reinforced our commitment to excellence.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-gray-600">
|
<p>
|
||||||
Today, we continue to push boundaries, embrace new technologies, and deliver
|
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.
|
||||||
solutions that exceed expectations. Our journey is far from over, and we're
|
|
||||||
excited about what the future holds.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-gradient-to-br from-primary-500 to-primary-700 rounded-2xl p-8 text-white">
|
</div>
|
||||||
<h3 class="text-2xl font-bold mb-6">Our Values</h3>
|
|
||||||
<ul class="space-y-4">
|
<!-- Values card -->
|
||||||
<li class="flex items-start">
|
<div class="card p-8" style="border: 1px solid rgba(92,184,44,0.25);">
|
||||||
<svg class="w-6 h-6 mr-3 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<h3 class="text-xl font-bold mb-7" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Our Values</h3>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
<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>
|
</svg>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="block">Quality First</strong>
|
<div class="font-semibold text-sm mb-0.5" style="color: #e8e6f0; font-family: 'Syne', sans-serif;">{{ title }}</div>
|
||||||
<span class="text-primary-100">We never compromise on quality, even under pressure.</span>
|
<div class="text-sm" style="color: #8b8ca8;">{{ desc }}</div>
|
||||||
</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>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Team Section -->
|
<!-- Team -->
|
||||||
<section class="bg-gray-100 py-20">
|
<section class="py-20 relative">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||||
<div class="text-center mb-16">
|
<div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Meet Our Team</h2>
|
<div class="text-center mb-14">
|
||||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
<div class="badge badge-primary mb-5">The Team</div>
|
||||||
A diverse group of talented individuals united by a shared passion for building great software.
|
<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>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
<div class="flex justify-center">
|
||||||
<div class="card text-center">
|
<div class="card-hover p-8 text-center max-w-xs w-full">
|
||||||
<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">
|
<div class="w-20 h-20 avatar text-2xl font-bold mx-auto mb-5">JH</div>
|
||||||
JH
|
<h3 class="text-lg font-bold mb-1" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Johannes</h3>
|
||||||
</div>
|
<p class="text-sm font-medium mb-4 gradient-text">Founder & CEO</p>
|
||||||
<h3 class="text-xl font-semibold text-gray-900">Johannes</h3>
|
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||||
<p class="text-accent-500 mb-3">Founder & CEO</p>
|
|
||||||
<p class="text-gray-600 text-sm">
|
|
||||||
25+ years in software development. Passionate about clean code and scalable architectures.
|
25+ years in software development. Passionate about clean code and scalable architectures.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -107,19 +92,26 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Mission Section -->
|
<!-- Mission -->
|
||||||
<section class="py-20">
|
<section class="py-24" style="background: #0a0a14;">
|
||||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
<div class="max-w-3xl 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>
|
<!-- Quote card -->
|
||||||
<p class="text-xl text-gray-600 mb-8">
|
<div class="inline-block p-px rounded-2xl w-full"
|
||||||
"To empower businesses with innovative software solutions that drive growth,
|
style="background: linear-gradient(135deg, rgba(92,184,44,0.35), rgba(247,147,30,0.15));">
|
||||||
improve efficiency, and create lasting value. We believe technology should
|
<div class="rounded-2xl px-10 py-14" style="background: #0f0f1a;">
|
||||||
be an enabler, not a barrier, and we're committed to making that a reality
|
<div class="text-4xl mb-6 gradient-text" style="font-family: 'Syne', sans-serif;">“</div>
|
||||||
for every client we work with."
|
<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>
|
</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-8 py-3.5">
|
||||||
Let's Work Together
|
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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -4,35 +4,41 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{% block title %}DirectLX{% endblock %} | DirectLX.dev</title>
|
<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">
|
<link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet">
|
||||||
<script src="{{ url_for('static', filename='js/htmx.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/htmx.min.js') }}"></script>
|
||||||
{% block head %}{% endblock %}
|
{% block head %}{% endblock %}
|
||||||
</head>
|
</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 -->
|
<!-- 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="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">
|
<div class="flex items-center">
|
||||||
<a href="{{ url_for('index') }}" class="flex items-center">
|
<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-14">
|
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-9 opacity-90 group-hover:opacity-100 transition-opacity">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Desktop Navigation -->
|
<!-- Desktop Navigation -->
|
||||||
<div class="hidden md:flex items-center space-x-8">
|
<div class="hidden md:flex items-center gap-1">
|
||||||
<a href="{{ url_for('index') }}" class="nav-link {% if request.endpoint == 'index' %}nav-link-active{% endif %}">Home</a>
|
<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 {% if request.endpoint == 'about' %}nav-link-active{% endif %}">About</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 {% if request.endpoint == 'services' %}nav-link-active{% endif %}">Services</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 {% if 'blog' in request.endpoint %}nav-link-active{% endif %}">Blog</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 {% if 'forum' in request.endpoint %}nav-link-active{% endif %}">Forum</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>
|
||||||
<a href="{{ url_for('contact') }}" class="btn btn-primary">Contact</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>
|
</div>
|
||||||
|
|
||||||
<!-- Mobile menu button -->
|
<!-- Mobile menu button -->
|
||||||
<div class="md:hidden flex items-center">
|
<div class="md:hidden flex items-center">
|
||||||
<button id="mobile-menu-btn" class="text-gray-600 hover:text-primary-600 focus:outline-none">
|
<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-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<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" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -41,14 +47,16 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Mobile Navigation -->
|
<!-- Mobile Navigation -->
|
||||||
<div id="mobile-menu" class="hidden md:hidden bg-white border-t">
|
<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-3 space-y-3">
|
<div class="px-4 py-4 space-y-1">
|
||||||
<a href="{{ url_for('index') }}" class="block nav-link">Home</a>
|
<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">About</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">Services</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">Blog</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">Forum</a>
|
<a href="{{ url_for('forum_index') }}" class="block nav-link px-4 py-2.5 rounded-lg hover:bg-white/5">Forum</a>
|
||||||
<a href="{{ url_for('contact') }}" class="block btn btn-primary text-center">Contact</a>
|
<div class="pt-2">
|
||||||
|
<a href="{{ url_for('contact') }}" class="btn btn-primary w-full">Contact</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
@ -56,9 +64,12 @@
|
||||||
<!-- Flash Messages -->
|
<!-- Flash Messages -->
|
||||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
{% if messages %}
|
{% 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 %}
|
{% 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 }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
@ -72,43 +83,45 @@
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<footer class="bg-gray-900 text-gray-300 mt-auto">
|
<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-12">
|
<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-8">
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-10">
|
||||||
<div class="col-span-1 md:col-span-2">
|
<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-9 mb-5 opacity-80">
|
||||||
<img src="{{ url_for('static', filename='images/directLX_small.png') }}" alt="DirectLX" class="h-14">
|
<p class="text-sm leading-relaxed" style="color: #6b6b8a; max-width: 300px;">
|
||||||
</div>
|
Building innovative software solutions that drive business growth. Custom development, consulting, and technical excellence.
|
||||||
<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.
|
|
||||||
</p>
|
</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>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-white font-semibold mb-4">Quick Links</h3>
|
<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-2">
|
<ul class="space-y-3">
|
||||||
<li><a href="{{ url_for('index') }}" class="hover:text-white transition-colors">Home</a></li>
|
<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="hover:text-white transition-colors">About</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="hover:text-white transition-colors">Services</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="hover:text-white transition-colors">Blog</a></li>
|
<li><a href="{{ url_for('blog_index') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Blog</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-white font-semibold mb-4">Community</h3>
|
<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-2">
|
<ul class="space-y-3">
|
||||||
<li><a href="{{ url_for('forum_index') }}" class="hover:text-white transition-colors">Forum</a></li>
|
<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="hover:text-white transition-colors">Contact</a></li>
|
<li><a href="{{ url_for('contact') }}" class="text-sm hover:text-white transition-colors" style="color: #8b8ca8;">Contact</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-500">
|
<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>© {{ now.year if now else '2024' }} DirectLX.dev. All rights reserved.</p>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Mobile menu toggle
|
|
||||||
document.getElementById('mobile-menu-btn').addEventListener('click', function() {
|
document.getElementById('mobile-menu-btn').addEventListener('click', function() {
|
||||||
document.getElementById('mobile-menu').classList.toggle('hidden');
|
document.getElementById('mobile-menu').classList.toggle('hidden');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,41 +3,42 @@
|
||||||
{% block title %}Blog{% endblock %}
|
{% block title %}Blog{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% 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 -->
|
<!-- Hero -->
|
||||||
<section class="py-8 bg-gray-100">
|
<section class="relative py-24 overflow-hidden">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<div class="max-w-xl mx-auto">
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[350px] pointer-events-none"
|
||||||
<div class="relative">
|
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"
|
<input type="text"
|
||||||
name="search"
|
name="search"
|
||||||
placeholder="Search posts..."
|
placeholder="Search posts…"
|
||||||
class="input pl-12"
|
class="input pl-11 pr-4 py-3.5"
|
||||||
hx-get="{{ url_for('blog_search') }}"
|
hx-get="{{ url_for('blog_search') }}"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
hx-trigger="keyup changed delay:500ms"
|
||||||
hx-target="#blog-posts"
|
hx-target="#blog-posts"
|
||||||
hx-swap="innerHTML">
|
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">
|
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Blog Posts -->
|
<!-- 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 class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div id="blog-posts">
|
<div id="blog-posts">
|
||||||
{% include "blog/partials/post_list.html" %}
|
{% include "blog/partials/post_list.html" %}
|
||||||
|
|
@ -45,14 +46,14 @@
|
||||||
|
|
||||||
<!-- Load More -->
|
<!-- Load More -->
|
||||||
{% if posts and posts|length >= 10 %}
|
{% 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) }}"
|
<button hx-get="{{ url_for('blog_load_more', page=2) }}"
|
||||||
hx-target="#blog-posts"
|
hx-target="#blog-posts"
|
||||||
hx-swap="beforeend"
|
hx-swap="beforeend"
|
||||||
hx-trigger="click"
|
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">
|
<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>
|
<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>
|
<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>
|
</svg>
|
||||||
|
|
@ -63,4 +64,5 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,40 @@
|
||||||
{% if posts %}
|
{% 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 %}
|
{% for post in posts %}
|
||||||
<article class="card hover:shadow-lg transition-shadow">
|
<article class="card-hover flex flex-col p-7 group">
|
||||||
<div class="text-sm text-gray-500 mb-2">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
<div class="text-xs font-medium tracking-wide mb-4" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||||
<h2 class="text-xl font-semibold text-gray-900 mb-2">
|
<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="hover:text-primary-600 transition-colors">
|
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-gray-100 hover:text-primary-300 transition-colors">
|
||||||
{{ post.title }}
|
{{ post.title }}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-gray-600 mb-4 line-clamp-3">
|
<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 %}
|
{{ post.excerpt or post.content[:150] }}{% if post.content|length > 150 %}…{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center justify-between">
|
<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 text-sm text-gray-500">
|
<div class="flex items-center gap-2.5">
|
||||||
<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">
|
<div class="avatar w-7 h-7 text-xs">{{ post.author.username[0].upper() }}</div>
|
||||||
{{ post.author.username[0].upper() }}
|
<span class="text-xs" style="color: #6b6b8a;">{{ post.author.username }}</span>
|
||||||
</div>
|
</div>
|
||||||
{{ post.author.username }}
|
<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">
|
||||||
</div>
|
Read more
|
||||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-primary-600 hover:text-primary-700 font-medium text-sm">
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
Read more →
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
|
||||||
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-center py-16">
|
<div class="text-center py-20">
|
||||||
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
<div class="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-5"
|
||||||
<svg class="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||||
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No posts yet</h3>
|
<h3 class="text-xl font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No posts yet</h3>
|
||||||
<p class="text-gray-600">Check back soon for new content!</p>
|
<p class="text-sm" style="color: #6b6b8a;">Check back soon for new content!</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
||||||
|
|
@ -3,45 +3,57 @@
|
||||||
{% block title %}{{ post.title }}{% endblock %}
|
{% block title %}{{ post.title }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<article class="py-16">
|
|
||||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
<article class="py-16 pb-28" style="background: #0a0a14;">
|
||||||
<!-- Post Header -->
|
<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">
|
<header class="mb-12">
|
||||||
<div class="flex items-center text-sm text-gray-500 mb-4">
|
<div class="badge badge-primary mb-6">Article</div>
|
||||||
<a href="{{ url_for('blog_index') }}" class="hover:text-primary-600">← Back to Blog</a>
|
<h1 class="text-4xl md:text-5xl font-extrabold mb-7 leading-tight" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||||
</div>
|
{{ post.title }}
|
||||||
<h1 class="text-4xl md:text-5xl font-bold text-gray-900 mb-6">{{ post.title }}</h1>
|
</h1>
|
||||||
<div class="flex items-center text-gray-600">
|
<div class="flex items-center gap-4 pb-8" style="border-bottom: 1px solid rgba(255,255,255,0.06);">
|
||||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold mr-3">
|
<div class="avatar w-10 h-10 text-sm font-bold">{{ post.author.username[0].upper() }}</div>
|
||||||
{{ post.author.username[0].upper() }}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<div class="font-medium text-gray-900">{{ post.author.username }}</div>
|
<div class="text-sm font-semibold" style="color: #e8e6f0;">{{ post.author.username }}</div>
|
||||||
<div class="text-sm">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
<div class="text-xs" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Post Content -->
|
<!-- Content -->
|
||||||
<div class="prose prose-lg max-w-none">
|
<div class="prose-dark leading-relaxed" style="font-size: 1.0625rem; line-height: 1.8;">
|
||||||
{{ post.content | safe }}
|
{{ post.content | safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Post Footer -->
|
<!-- Footer -->
|
||||||
<footer class="mt-12 pt-8 border-t border-gray-200">
|
<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 class="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
{% if post.updated_at and post.updated_at != post.created_at %}
|
{% if post.updated_at and post.updated_at != post.created_at %}
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-xs" style="color: #6b6b8a;">Last updated: {{ post.updated_at.strftime('%B %d, %Y') }}</p>
|
||||||
Last updated: {{ post.updated_at.strftime('%B %d, %Y') }}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ url_for('blog_index') }}" class="btn btn-secondary">
|
<a href="{{ url_for('blog_index') }}" class="btn btn-outline">
|
||||||
← Back to Blog
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,48 +3,49 @@
|
||||||
{% block title %}Contact{% endblock %}
|
{% block title %}Contact{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Hero Section -->
|
|
||||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-20">
|
<!-- Hero -->
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<section class="relative py-28 overflow-hidden">
|
||||||
<div class="text-center">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">Get in Touch</h1>
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[400px] pointer-events-none"
|
||||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||||
Have a project in mind? We'd love to hear from you.
|
|
||||||
Send us a message and we'll respond as soon as possible.
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Contact Section -->
|
<!-- Contact Section -->
|
||||||
<section class="py-20">
|
<section class="py-12 pb-28" style="background: #0a0a14;">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-10">
|
||||||
|
|
||||||
<!-- Contact Form -->
|
<!-- Contact Form -->
|
||||||
<div class="card">
|
<div class="lg:col-span-3">
|
||||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Send us a Message</h2>
|
<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"
|
<form id="contact-form"
|
||||||
hx-post="{{ url_for('contact_submit') }}"
|
hx-post="{{ url_for('contact_submit') }}"
|
||||||
hx-target="#form-response"
|
hx-target="#form-response"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
class="space-y-6">
|
class="space-y-5">
|
||||||
<div>
|
<div>
|
||||||
<label for="name" class="label">Your Name</label>
|
<label for="name" class="label">Your Name</label>
|
||||||
<input type="text" id="name" name="name" required
|
<input type="text" id="name" name="name" required class="input" placeholder="Jane Smith">
|
||||||
class="input"
|
|
||||||
placeholder="John Doe">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="email" class="label">Email Address</label>
|
<label for="email" class="label">Email Address</label>
|
||||||
<input type="email" id="email" name="email" required
|
<input type="email" id="email" name="email" required class="input" placeholder="jane@company.com">
|
||||||
class="input"
|
|
||||||
placeholder="john@example.com">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="subject" class="label">Subject</label>
|
<label for="subject" class="label">Subject</label>
|
||||||
<input type="text" id="subject" name="subject" required
|
<input type="text" id="subject" name="subject" required class="input" placeholder="Project Inquiry">
|
||||||
class="input"
|
|
||||||
placeholder="Project Inquiry">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="message" class="label">Message</label>
|
<label for="message" class="label">Message</label>
|
||||||
|
|
@ -52,9 +53,9 @@
|
||||||
class="input resize-none"
|
class="input resize-none"
|
||||||
placeholder="Tell us about your project..."></textarea>
|
placeholder="Tell us about your project..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-accent w-full py-3">
|
<button type="submit" class="btn btn-primary w-full py-3.5">
|
||||||
<span class="htmx-indicator">
|
<span class="htmx-indicator mr-2">
|
||||||
<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">
|
<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>
|
<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>
|
<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>
|
</svg>
|
||||||
|
|
@ -64,72 +65,81 @@
|
||||||
</form>
|
</form>
|
||||||
<div id="form-response" class="mt-4"></div>
|
<div id="form-response" class="mt-4"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Contact Info -->
|
<!-- Contact Info -->
|
||||||
<div class="space-y-8">
|
<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>
|
<div>
|
||||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Contact Information</h2>
|
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Email</div>
|
||||||
<p class="text-gray-600 mb-8">
|
<div class="text-sm font-medium" style="color: #e8e6f0;">hello@directlx.dev</div>
|
||||||
Feel free to reach out through the form or use any of the contact methods below.
|
</div>
|
||||||
We typically respond within 24 hours.
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||||
<div class="flex items-start">
|
<div class="flex items-start gap-4">
|
||||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
<div class="w-10 h-10 rounded-xl 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">
|
style="background: rgba(247,147,30,0.08); border: 1px solid rgba(247,147,30,0.2);">
|
||||||
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div>
|
||||||
<h3 class="text-lg font-semibold text-gray-900">Email</h3>
|
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Location</div>
|
||||||
<p class="text-gray-600">hello@directlx.dev</p>
|
<div class="text-sm font-medium" style="color: #e8e6f0;">Remote — Worldwide</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start">
|
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||||
<div class="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
<div class="flex items-start gap-4">
|
||||||
<svg class="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<div class="w-10 h-10 rounded-xl flex items-center justify-center flex-shrink-0"
|
||||||
<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" />
|
style="background: rgba(92,184,44,0.12); border: 1px solid rgba(92,184,44,0.25);">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div>
|
||||||
<h3 class="text-lg font-semibold text-gray-900">Location</h3>
|
<div class="text-xs font-semibold tracking-wider uppercase mb-1" style="color: #6b6b8a; font-family: 'Syne', sans-serif;">Response Time</div>
|
||||||
<p class="text-gray-600">Remote - Worldwide</p>
|
<div class="text-sm font-medium" style="color: #e8e6f0;">Within 24 hours</div>
|
||||||
</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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Social Links -->
|
<!-- Social links -->
|
||||||
<div class="pt-8 border-t border-gray-200">
|
<div class="card p-6" style="border: 1px solid rgba(255,255,255,0.06);">
|
||||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Follow Us</h3>
|
<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 space-x-4">
|
<div class="flex gap-3">
|
||||||
<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">
|
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
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"/>
|
<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>
|
</svg>
|
||||||
</a>
|
</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">
|
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
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"/>
|
<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>
|
</svg>
|
||||||
</a>
|
</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">
|
<a href="#" class="w-9 h-9 rounded-lg flex items-center justify-center transition-all"
|
||||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
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"/>
|
<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>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -139,4 +149,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,51 +3,61 @@
|
||||||
{% block title %}{{ category.name }} - Forum{% endblock %}
|
{% block title %}{{ category.name }} - Forum{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<!-- Category Header -->
|
<!-- Category Header -->
|
||||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-12">
|
<section class="relative py-20 overflow-hidden">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<div class="flex items-center text-sm text-gray-400 mb-4">
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[500px] h-[300px] pointer-events-none"
|
||||||
<a href="{{ url_for('forum_index') }}" class="hover:text-white">← Back to Forum</a>
|
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>
|
</div>
|
||||||
<h1 class="text-3xl md:text-4xl font-bold mb-2">{{ category.name }}</h1>
|
<div class="badge badge-primary mb-4">Category</div>
|
||||||
<p class="text-gray-300">{{ category.description }}</p>
|
<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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- New Topic Button & Topics List -->
|
<!-- Topics -->
|
||||||
<section class="py-8">
|
<section class="py-10 pb-24" style="background: #0a0a14;">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center mb-8">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h2 class="text-xl font-bold text-gray-900">{{ topics.total if topics else 0 }} Topics</h2>
|
<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')"
|
<button onclick="document.getElementById('new-topic-modal').classList.remove('hidden')"
|
||||||
class="btn btn-primary">
|
class="btn btn-primary text-sm">
|
||||||
<svg class="w-5 h-5 mr-2 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<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" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
||||||
</svg>
|
</svg>
|
||||||
New Topic
|
New Topic
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Topics List -->
|
|
||||||
<div id="topics-list">
|
<div id="topics-list">
|
||||||
{% include "forum/partials/topic_list.html" %}
|
{% include "forum/partials/topic_list.html" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Pagination -->
|
<!-- Pagination -->
|
||||||
{% if topics and topics.pages > 1 %}
|
{% 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 %}
|
{% 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
|
← Previous
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="btn btn-secondary">Page {{ topics.page }} of {{ topics.pages }}</span>
|
||||||
<span class="btn bg-gray-100 text-gray-600">
|
|
||||||
Page {{ topics.page }} of {{ topics.pages }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{% if topics.has_next %}
|
{% 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 →
|
Next →
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
@ -57,12 +67,15 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- New Topic Modal -->
|
<!-- 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 id="new-topic-modal" class="fixed inset-0 hidden z-50 flex items-center justify-center p-4"
|
||||||
<div class="bg-white rounded-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
|
style="background: rgba(0,0,0,0.7); backdrop-filter: blur(8px);">
|
||||||
<div class="p-6 border-b border-gray-200 flex justify-between items-center">
|
<div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-2xl"
|
||||||
<h3 class="text-xl font-bold text-gray-900">Create New Topic</h3>
|
style="background: #0f0f1a; border: 1px solid rgba(92,184,44,0.3); box-shadow: 0 0 60px rgba(92,184,44,0.15);">
|
||||||
<button onclick="document.getElementById('new-topic-modal').classList.add('hidden')" class="text-gray-500 hover:text-gray-700">
|
<div class="flex justify-between items-center px-7 py-5" style="border-bottom: 1px solid rgba(255,255,255,0.06);">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<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" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -71,42 +84,33 @@
|
||||||
hx-target="#topics-list"
|
hx-target="#topics-list"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-on::after-request="if(event.detail.successful) document.getElementById('new-topic-modal').classList.add('hidden')"
|
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>
|
<div>
|
||||||
<label for="title" class="label">Topic Title</label>
|
<label for="title" class="label">Topic Title</label>
|
||||||
<input type="text" id="title" name="title" required class="input" placeholder="Enter a descriptive title">
|
<input type="text" id="title" name="title" required class="input" placeholder="Enter a descriptive title">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="content" class="label">Content</label>
|
<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>
|
||||||
<div class="flex justify-end space-x-3">
|
<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">
|
<button type="button" onclick="document.getElementById('new-topic-modal').classList.add('hidden')"
|
||||||
Cancel
|
class="btn btn-secondary">Cancel</button>
|
||||||
</button>
|
<button type="submit" class="btn btn-primary">Create Topic</button>
|
||||||
<button type="submit" class="btn btn-primary">
|
|
||||||
Create Topic
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script>
|
<script>
|
||||||
// Close modal on escape key
|
|
||||||
document.addEventListener('keydown', function(e) {
|
document.addEventListener('keydown', function(e) {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') document.getElementById('new-topic-modal').classList.add('hidden');
|
||||||
document.getElementById('new-topic-modal').classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close modal on backdrop click
|
|
||||||
document.getElementById('new-topic-modal').addEventListener('click', function(e) {
|
document.getElementById('new-topic-modal').addEventListener('click', function(e) {
|
||||||
if (e.target === this) {
|
if (e.target === this) this.classList.add('hidden');
|
||||||
this.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,108 +3,123 @@
|
||||||
{% block title %}Forum{% endblock %}
|
{% block title %}Forum{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Hero Section -->
|
|
||||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-16">
|
<!-- Hero -->
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<section class="relative py-24 overflow-hidden">
|
||||||
<div class="text-center">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<h1 class="text-4xl md:text-5xl font-bold mb-4">Community Forum</h1>
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[350px] pointer-events-none"
|
||||||
<p class="text-xl text-gray-300 max-w-2xl mx-auto">
|
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.
|
Connect with other developers, ask questions, share knowledge, and grow together.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Forum Categories -->
|
<!-- Search -->
|
||||||
<section class="py-16">
|
<div class="max-w-md mx-auto relative">
|
||||||
<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"
|
<input type="text"
|
||||||
placeholder="Search topics..."
|
placeholder="Search topics…"
|
||||||
class="input pl-10"
|
class="input pl-11 py-3.5"
|
||||||
hx-get="{{ url_for('forum_search') }}"
|
hx-get="{{ url_for('forum_search') }}"
|
||||||
hx-trigger="keyup changed delay:500ms"
|
hx-trigger="keyup changed delay:500ms"
|
||||||
hx-target="#search-results"
|
hx-target="#search-results"
|
||||||
name="q">
|
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">
|
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Search Results Container -->
|
<!-- Categories -->
|
||||||
<div id="search-results" class="mb-8"></div>
|
<section class="py-16" style="background: #0a0a14;">
|
||||||
|
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
|
||||||
|
<!-- 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 %}
|
{% if categories %}
|
||||||
<div class="space-y-4">
|
<div class="space-y-3">
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
<a href="{{ url_for('forum_category', slug=category.slug) }}" class="card block hover:shadow-lg transition-shadow group">
|
<a href="{{ url_for('forum_category', slug=category.slug) }}"
|
||||||
<div class="flex items-start">
|
class="card-hover flex items-center gap-5 p-6 group block">
|
||||||
<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">
|
<div class="w-11 h-11 rounded-xl 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">
|
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||||
<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 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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex-grow">
|
<div class="flex-grow min-w-0">
|
||||||
<h3 class="text-xl font-semibold text-gray-900 group-hover:text-primary-600 transition-colors">
|
<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 }}
|
{{ category.name }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-gray-600 mt-1">{{ category.description }}</p>
|
<p class="text-sm truncate" style="color: #8b8ca8;">{{ category.description }}</p>
|
||||||
</div>
|
|
||||||
<div class="text-right text-sm text-gray-500">
|
|
||||||
<div>{{ category.topics.count() }} topics</div>
|
|
||||||
</div>
|
</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>
|
</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>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-center py-16">
|
<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">
|
<div class="w-14 h-14 rounded-xl 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">
|
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||||
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No categories yet</h3>
|
<h3 class="text-lg font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No categories yet</h3>
|
||||||
<p class="text-gray-600">The forum is being set up. Check back soon!</p>
|
<p class="text-sm" style="color: #6b6b8a;">The forum is being set up. Check back soon!</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Recent Activity -->
|
<!-- Recent Activity -->
|
||||||
<section class="bg-gray-100 py-16">
|
<section class="py-16 relative">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="absolute inset-0 dot-grid opacity-20 pointer-events-none"></div>
|
||||||
<h2 class="text-2xl font-bold text-gray-900 mb-8">Recent Activity</h2>
|
<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 %}
|
{% if recent_topics %}
|
||||||
<div class="space-y-4">
|
<div class="space-y-3">
|
||||||
{% for topic in recent_topics %}
|
{% for topic in recent_topics %}
|
||||||
<div class="card flex items-center">
|
<div class="card flex items-center gap-4 p-5" style="border: 1px solid rgba(255,255,255,0.05);">
|
||||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold mr-4">
|
<div class="avatar w-9 h-9 text-xs font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||||
{{ topic.author.username[0].upper() }}
|
<div class="flex-grow min-w-0">
|
||||||
</div>
|
<a href="{{ url_for('forum_topic', category_slug=topic.category.slug, topic_id=topic.id) }}"
|
||||||
<div class="flex-grow">
|
class="text-sm font-semibold text-gray-200 hover:text-primary-300 transition-colors truncate block">
|
||||||
<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">
|
|
||||||
{{ topic.title }}
|
{{ topic.title }}
|
||||||
</a>
|
</a>
|
||||||
<div class="text-sm text-gray-500">
|
<div class="text-xs mt-0.5" style="color: #6b6b8a;">
|
||||||
by {{ topic.author.username }} in
|
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>
|
</div>
|
||||||
<div class="text-sm text-gray-500">
|
<div class="flex-shrink-0 text-right">
|
||||||
{{ topic.reply_count }} replies
|
<div class="text-xs font-semibold" style="color: #e8e6f0;">{{ topic.reply_count }}</div>
|
||||||
|
<div class="text-xs" style="color: #6b6b8a;">replies</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% 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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="card">
|
<div class="card p-7" style="border: 1px solid rgba(92,184,44,0.2);">
|
||||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Add a Reply</h3>
|
<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) }}"
|
<form hx-post="{{ url_for('forum_add_reply', category_slug=topic.category.slug, topic_id=topic.id) }}"
|
||||||
hx-target="#replies-list"
|
hx-target="#replies-list"
|
||||||
hx-swap="beforeend"
|
hx-swap="beforeend"
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<textarea name="content" rows="4" required
|
<textarea name="content" rows="4" required
|
||||||
class="input resize-none"
|
class="input resize-none"
|
||||||
placeholder="Write your reply..."></textarea>
|
placeholder="Write your reply…"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,43 @@
|
||||||
{% if topics and topics.items %}
|
{% if topics and topics.items %}
|
||||||
<div class="space-y-4">
|
<div class="space-y-3">
|
||||||
{% for topic in topics.items %}
|
{% 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="card flex items-center gap-4 p-5 transition-all duration-300 group
|
||||||
<div class="flex items-start">
|
{% if topic.is_pinned %}{% else %}{% endif %}"
|
||||||
<div class="w-10 h-10 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold flex-shrink-0">
|
style="border: 1px solid {% if topic.is_pinned %}rgba(92,184,44,0.3){% else %}rgba(255,255,255,0.05){% endif %};">
|
||||||
{{ topic.author.username[0].upper() }}
|
<div class="avatar w-10 h-10 text-sm font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||||
</div>
|
<div class="flex-grow min-w-0">
|
||||||
<div class="ml-4 flex-grow">
|
<div class="flex items-center gap-2 mb-1 flex-wrap">
|
||||||
<div class="flex items-center mb-1">
|
|
||||||
{% if topic.is_pinned %}
|
{% if topic.is_pinned %}
|
||||||
<span class="bg-primary-100 text-primary-600 text-xs px-2 py-0.5 rounded mr-2">Pinned</span>
|
<span class="badge badge-primary text-xs">Pinned</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if topic.is_locked %}
|
{% if topic.is_locked %}
|
||||||
<span class="bg-red-100 text-red-600 text-xs px-2 py-0.5 rounded mr-2">Locked</span>
|
<span class="badge badge-red text-xs">Locked</span>
|
||||||
{% endif %}
|
{% 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">
|
<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 }}
|
{{ topic.title }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm text-gray-500">
|
<div class="text-xs" style="color: #6b6b8a;">
|
||||||
by {{ topic.author.username }} · {{ topic.created_at.strftime('%B %d, %Y') }}
|
by {{ topic.author.username }} · {{ topic.created_at.strftime('%b %d, %Y') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-right text-sm text-gray-500 flex-shrink-0">
|
<div class="text-right flex-shrink-0">
|
||||||
<div class="font-medium">{{ topic.reply_count }} replies</div>
|
<div class="text-sm font-semibold" style="color: #e8e6f0;">{{ topic.reply_count }}</div>
|
||||||
<div>Last activity: {{ topic.last_activity.strftime('%b %d') }}</div>
|
<div class="text-xs" style="color: #6b6b8a;">{{ topic.last_activity.strftime('%b %d') }}</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-center py-16">
|
<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">
|
<div class="w-14 h-14 rounded-xl 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">
|
style="background: rgba(92,184,44,0.1); border: 1px solid rgba(92,184,44,0.2);">
|
||||||
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">No topics yet</h3>
|
<h3 class="text-lg font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">No topics yet</h3>
|
||||||
<p class="text-gray-600">Be the first to start a discussion!</p>
|
<p class="text-sm" style="color: #6b6b8a;">Be the first to start a discussion!</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
||||||
|
|
@ -3,55 +3,55 @@
|
||||||
{% block title %}{{ topic.title }} - Forum{% endblock %}
|
{% block title %}{{ topic.title }} - Forum{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<!-- Topic Header -->
|
<!-- Topic Header -->
|
||||||
<section class="bg-gradient-to-br from-gray-800 to-gray-900 text-white py-8">
|
<section class="relative py-16 overflow-hidden">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="absolute inset-0 dot-grid opacity-25 pointer-events-none"></div>
|
||||||
<div class="flex items-center text-sm text-gray-400 mb-4">
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[500px] h-[250px] pointer-events-none"
|
||||||
<a href="{{ url_for('forum_index') }}" class="hover:text-white">Forum</a>
|
style="background: radial-gradient(ellipse, rgba(92,184,44,0.08) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||||
<span class="mx-2">/</span>
|
|
||||||
<a href="{{ url_for('forum_category', slug=topic.category.slug) }}" class="hover:text-white">{{ topic.category.name }}</a>
|
<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>
|
||||||
<div class="flex items-start justify-between">
|
|
||||||
|
<div class="flex items-start justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl md:text-3xl font-bold mb-2">
|
<div class="flex items-center gap-2 mb-3 flex-wrap">
|
||||||
{% if topic.is_pinned %}
|
{% if topic.is_pinned %}<span class="badge badge-primary">Pinned</span>{% endif %}
|
||||||
<svg class="w-5 h-5 inline mr-2 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
|
{% if topic.is_locked %}<span class="badge badge-red">Locked</span>{% endif %}
|
||||||
<path d="M5 5a2 2 0 012-2h6a2 2 0 012 2v2a2 2 0 01-2 2H7a2 2 0 01-2-2V5z"/>
|
</div>
|
||||||
<path d="M8 12a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z"/>
|
<h1 class="text-3xl md:text-4xl font-extrabold leading-tight mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||||
<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 %}
|
|
||||||
{{ topic.title }}
|
{{ 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>
|
</h1>
|
||||||
<div class="text-gray-400 text-sm">
|
<div class="text-sm" style="color: #6b6b8a;">
|
||||||
Started by {{ topic.author.username }} · {{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}
|
Started by <span style="color: #c4c2d4;">{{ topic.author.username }}</span>
|
||||||
|
· {{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Original Post -->
|
<!-- Posts & Replies -->
|
||||||
<section class="py-8">
|
<section class="pb-24" style="background: #0a0a14;">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="card mb-6">
|
|
||||||
<div class="flex items-start">
|
<!-- Original post -->
|
||||||
<div class="w-12 h-12 bg-primary-100 rounded-full flex items-center justify-center text-primary-600 font-semibold flex-shrink-0">
|
<div class="card p-7 mb-4" style="border: 1px solid rgba(92,184,44,0.2);">
|
||||||
{{ topic.author.username[0].upper() }}
|
<div class="flex items-start gap-4">
|
||||||
</div>
|
<div class="avatar w-11 h-11 text-sm font-bold flex-shrink-0">{{ topic.author.username[0].upper() }}</div>
|
||||||
<div class="ml-4 flex-grow">
|
<div class="flex-grow min-w-0">
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div class="font-medium text-gray-900">{{ topic.author.username }}</div>
|
<div class="font-semibold text-sm" style="color: #e8e6f0;">{{ topic.author.username }}</div>
|
||||||
<div class="text-sm text-gray-500">{{ topic.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
<div class="text-xs" style="color: #6b6b8a;">{{ 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 }}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="prose-dark text-sm leading-relaxed">{{ topic.content | safe }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -59,21 +59,19 @@
|
||||||
<!-- Replies -->
|
<!-- Replies -->
|
||||||
<div id="replies-list">
|
<div id="replies-list">
|
||||||
{% if replies %}
|
{% 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 %}
|
{% for reply in replies %}
|
||||||
<div class="card mb-4">
|
<div class="card p-6 mb-3" style="border: 1px solid rgba(255,255,255,0.05);">
|
||||||
<div class="flex items-start">
|
<div class="flex items-start gap-4">
|
||||||
<div class="w-10 h-10 bg-gray-100 rounded-full flex items-center justify-center text-gray-600 font-semibold flex-shrink-0">
|
<div class="avatar w-9 h-9 text-xs font-bold flex-shrink-0">{{ reply.author.username[0].upper() }}</div>
|
||||||
{{ reply.author.username[0].upper() }}
|
<div class="flex-grow min-w-0">
|
||||||
</div>
|
<div class="flex items-center justify-between mb-3">
|
||||||
<div class="ml-4 flex-grow">
|
<div class="font-semibold text-sm" style="color: #e8e6f0;">{{ reply.author.username }}</div>
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="text-xs" style="color: #6b6b8a;">{{ reply.created_at.strftime('%B %d, %Y at %H:%M') }}</div>
|
||||||
<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>
|
</div>
|
||||||
|
<div class="prose-dark text-sm leading-relaxed">{{ reply.content | safe }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -81,19 +79,20 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Reply Form -->
|
<!-- Reply form or locked message -->
|
||||||
{% if not topic.is_locked %}
|
{% 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" %}
|
{% include "forum/partials/reply_form.html" %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="card text-center py-8 text-gray-500">
|
<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-12 h-12 mx-auto mb-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<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="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" />
|
<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>
|
</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>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,134 +3,178 @@
|
||||||
{% block title %}Home{% endblock %}
|
{% block title %}Home{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<!-- Hero Section -->
|
<!-- Hero Section -->
|
||||||
<section class="bg-gradient-to-br from-primary-600 to-primary-800 text-white">
|
<section class="relative overflow-hidden" style="min-height: 88vh; display: flex; align-items: center;">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-24">
|
<!-- Background glow orbs -->
|
||||||
<div class="text-center">
|
<div class="absolute inset-0 pointer-events-none">
|
||||||
<h1 class="text-4xl md:text-6xl font-bold mb-6">
|
<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>
|
Build Better Software,<br>
|
||||||
<span class="text-accent-400">Faster</span>
|
<span class="gradient-text">Faster.</span>
|
||||||
</h1>
|
</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.
|
<p class="text-lg md:text-xl max-w-2xl mx-auto mb-10" style="color: #8b8ca8; line-height: 1.7;">
|
||||||
From concept to deployment, we're your trusted development partner.
|
We transform ideas into powerful, scalable software.
|
||||||
|
From concept to deployment — your trusted development partner.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
<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">
|
<a href="{{ url_for('contact') }}" class="btn btn-primary px-8 py-3.5 text-base">
|
||||||
Get Started
|
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>
|
||||||
<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">
|
<a href="{{ url_for('services') }}" class="btn btn-outline px-8 py-3.5 text-base">
|
||||||
Our Services
|
Our Services
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Features Section -->
|
<!-- Features Section -->
|
||||||
<section class="py-20">
|
<section class="py-24 relative">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<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">
|
<div class="text-center mb-16">
|
||||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Why Choose DirectLX?</h2>
|
<div class="badge badge-primary mb-5">Why DirectLX</div>
|
||||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
<h2 class="text-3xl md:text-4xl font-bold mb-4" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||||
We combine technical expertise with a deep understanding of business needs
|
Engineering excellence,<br><span class="gradient-text">by design</span>
|
||||||
to deliver solutions that truly make a difference.
|
</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>
|
</p>
|
||||||
</div>
|
</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">
|
||||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
<!-- Card 1 -->
|
||||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
<div class="card-hover group p-8">
|
||||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Fast Delivery</h3>
|
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Fast Delivery</h3>
|
||||||
<p class="text-gray-600">
|
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||||
Agile methodology and modern tools ensure rapid development without compromising quality.
|
Agile methodology and modern tooling ensure rapid iteration without sacrificing quality or reliability.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
<!-- Card 2 -->
|
||||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
<div class="card-hover group p-8">
|
||||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||||
<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" />
|
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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Secure & Reliable</h3>
|
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Secure & Reliable</h3>
|
||||||
<p class="text-gray-600">
|
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||||
Security-first approach with industry best practices and thorough testing.
|
Security-first architecture with industry best practices and thorough testing at every stage.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card text-center hover:shadow-lg transition-shadow">
|
<!-- Card 3 -->
|
||||||
<div class="w-16 h-16 bg-primary-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
<div class="card-hover group p-8">
|
||||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6"
|
||||||
<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" />
|
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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Expert Team</h3>
|
<h3 class="text-lg font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">Expert Team</h3>
|
||||||
<p class="text-gray-600">
|
<p class="text-sm leading-relaxed" style="color: #8b8ca8;">
|
||||||
Experienced developers passionate about creating exceptional software solutions.
|
Seasoned engineers passionate about clean code, scalable architecture, and exceptional outcomes.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</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 -->
|
<!-- 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="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center mb-12">
|
<div class="flex justify-between items-end mb-12">
|
||||||
<h2 class="text-3xl font-bold text-gray-900">Latest from the Blog</h2>
|
<div>
|
||||||
<a href="{{ url_for('blog_index') }}" class="text-primary-600 hover:text-primary-700 font-medium">
|
<div class="badge badge-primary mb-4">From the Blog</div>
|
||||||
View all posts →
|
<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>
|
</a>
|
||||||
</div>
|
</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 %}
|
{% if latest_posts %}
|
||||||
{% for post in latest_posts %}
|
{% for post in latest_posts %}
|
||||||
<article class="card hover:shadow-lg transition-shadow">
|
<article class="card-hover group flex flex-col p-7">
|
||||||
<div class="text-sm text-gray-500 mb-2">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
<div class="text-xs mb-4 font-medium tracking-wide" style="color: #6b6b8a;">{{ post.created_at.strftime('%B %d, %Y') }}</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">
|
<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="hover:text-primary-600">
|
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-gray-100 hover:text-primary-300 transition-colors">
|
||||||
{{ post.title }}
|
{{ post.title }}
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-gray-600 mb-4">{{ post.excerpt or post.content[:150] }}...</p>
|
<p class="text-sm leading-relaxed mb-6 flex-grow" style="color: #8b8ca8;">
|
||||||
<a href="{{ url_for('blog_post', slug=post.slug) }}" class="text-primary-600 hover:text-primary-700 font-medium">
|
{{ post.excerpt or post.content[:140] }}…
|
||||||
Read more →
|
</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>
|
</a>
|
||||||
</article>
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-span-3 text-center text-gray-500 py-8">
|
<div class="col-span-3 text-center py-12" style="color: #6b6b8a;">
|
||||||
<p>No blog posts yet. Check back soon!</p>
|
<p>No posts yet — check back soon.</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -138,16 +182,31 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- CTA Section -->
|
<!-- CTA Section -->
|
||||||
<section class="bg-primary-600 text-white py-16">
|
<section class="py-24 relative overflow-hidden">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
<div class="absolute inset-0 pointer-events-none">
|
||||||
<h2 class="text-3xl font-bold mb-4">Ready to Start Your Project?</h2>
|
<div class="absolute inset-0 dot-grid opacity-30"></div>
|
||||||
<p class="text-primary-100 max-w-2xl mx-auto mb-8">
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[600px] h-[300px]"
|
||||||
Let's discuss how we can help bring your vision to life.
|
style="background: radial-gradient(ellipse, rgba(92,184,44,0.15) 0%, transparent 70%); filter: blur(30px);"></div>
|
||||||
Get in touch for a free consultation.
|
</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>
|
</p>
|
||||||
<a href="{{ url_for('contact') }}" class="btn bg-white text-primary-600 hover:bg-gray-100 px-8 py-3 text-lg">
|
<a href="{{ url_for('contact') }}" class="btn btn-primary px-10 py-3.5 text-base">
|
||||||
Contact Us Today
|
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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -3,216 +3,137 @@
|
||||||
{% block title %}Services{% endblock %}
|
{% block title %}Services{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<!-- Hero Section -->
|
|
||||||
<section class="bg-gradient-to-br from-primary-600 to-primary-800 text-white py-20">
|
<!-- Hero -->
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<section class="relative py-28 overflow-hidden">
|
||||||
<div class="text-center">
|
<div class="absolute inset-0 dot-grid opacity-30 pointer-events-none"></div>
|
||||||
<h1 class="text-4xl md:text-5xl font-bold mb-6">Our Services</h1>
|
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-[700px] h-[400px] pointer-events-none"
|
||||||
<p class="text-xl text-primary-100 max-w-2xl mx-auto">
|
style="background: radial-gradient(ellipse, rgba(92,184,44,0.1) 0%, transparent 70%); filter: blur(40px);"></div>
|
||||||
Comprehensive software solutions tailored to your business needs.
|
|
||||||
From development to deployment, we've got you covered.
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Services Grid -->
|
<!-- 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="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">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<!-- 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>
|
|
||||||
|
|
||||||
<!-- API Development -->
|
{% set services = [
|
||||||
<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">
|
'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',
|
||||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
'title': 'Web Development',
|
||||||
<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" />
|
'desc': 'Modern, responsive websites and web applications built with the latest technologies. From simple landing pages to complex enterprise platforms.',
|
||||||
</svg>
|
'items': ['Custom web applications', 'E-commerce solutions', 'Progressive Web Apps (PWAs)'],
|
||||||
</div>
|
'accent': 'primary'
|
||||||
<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
|
'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',
|
||||||
with third-party services.
|
'title': 'API Development',
|
||||||
</p>
|
'desc': 'Robust, scalable APIs that power your applications and enable seamless integrations with third-party services.',
|
||||||
<ul class="text-gray-600 space-y-2">
|
'items': ['RESTful API design', 'GraphQL implementations', 'Third-party integrations'],
|
||||||
<li class="flex items-center">
|
'accent': 'accent'
|
||||||
<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>
|
'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',
|
||||||
RESTful API design
|
'title': 'Cloud Solutions',
|
||||||
</li>
|
'desc': 'Leverage the power of cloud computing with our expertise in AWS, Azure, and Google Cloud Platform.',
|
||||||
<li class="flex items-center">
|
'items': ['Cloud architecture design', 'Migration services', 'DevOps & CI/CD pipelines'],
|
||||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
'accent': 'accent'
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
},
|
||||||
</svg>
|
{
|
||||||
GraphQL implementations
|
'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',
|
||||||
</li>
|
'title': 'Technical Consulting',
|
||||||
<li class="flex items-center">
|
'desc': 'Expert guidance on technology strategy, architecture decisions, and best practices for your development team.',
|
||||||
<svg class="w-5 h-5 text-primary-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
'items': ['Technology assessment', 'Code reviews & audits', 'Team training'],
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
'accent': 'primary'
|
||||||
</svg>
|
},
|
||||||
Third-party integrations
|
] %}
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Cloud Solutions -->
|
{% for svc in services %}
|
||||||
<div class="card hover:shadow-lg transition-shadow">
|
<div class="card-hover p-8">
|
||||||
<div class="w-14 h-14 bg-primary-100 rounded-xl flex items-center justify-center mb-4">
|
<div class="w-12 h-12 rounded-xl flex items-center justify-center mb-6 flex-shrink-0"
|
||||||
<svg class="w-8 h-8 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
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);">
|
||||||
<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" />
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-2xl font-semibold text-gray-900 mb-3">Cloud Solutions</h3>
|
<h3 class="text-xl font-bold mb-3" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">{{ svc.title }}</h3>
|
||||||
<p class="text-gray-600 mb-4">
|
<p class="text-sm leading-relaxed mb-6" style="color: #8b8ca8;">{{ svc.desc }}</p>
|
||||||
Leverage the power of cloud computing with our expertise in AWS, Azure, and
|
<ul class="space-y-2.5">
|
||||||
Google Cloud Platform.
|
{% for item in svc.items %}
|
||||||
</p>
|
<li class="flex items-center gap-3 text-sm" style="color: #c4c2d4;">
|
||||||
<ul class="text-gray-600 space-y-2">
|
<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>
|
||||||
<li class="flex items-center">
|
{{ item }}
|
||||||
<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
|
|
||||||
</li>
|
</li>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Process Section -->
|
<!-- Process -->
|
||||||
<section class="bg-gray-100 py-20">
|
<section class="py-24 relative">
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<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">
|
<div class="text-center mb-16">
|
||||||
<h2 class="text-3xl font-bold text-gray-900 mb-4">Our Process</h2>
|
<div class="badge badge-primary mb-5">How We Work</div>
|
||||||
<p class="text-gray-600 max-w-2xl mx-auto">
|
<h2 class="text-3xl font-bold" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||||
A structured approach that ensures quality delivery and client satisfaction.
|
A process built for<br><span class="gradient-text">results</span>
|
||||||
</p>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 relative">
|
||||||
<div class="text-center">
|
<!-- Connector line -->
|
||||||
<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">
|
<div class="hidden md:block absolute top-9 left-[12.5%] right-[12.5%] h-px"
|
||||||
1
|
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>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900 mb-2">Discovery</h3>
|
<h3 class="text-base font-bold mb-2" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">{{ title }}</h3>
|
||||||
<p class="text-gray-600">Understanding your requirements, goals, and challenges.</p>
|
<p class="text-sm" style="color: #8b8ca8;">{{ desc }}</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>
|
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- CTA Section -->
|
<!-- CTA -->
|
||||||
<section class="py-20">
|
<section class="py-20" style="background: #0a0a14;">
|
||||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
<div class="max-w-2xl 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>
|
<h2 class="text-3xl font-bold mb-4" style="font-family: 'Syne', sans-serif; color: #f1f0ff;">
|
||||||
<p class="text-gray-600 mb-8 max-w-2xl mx-auto">
|
Ready to get <span class="gradient-text">started?</span>
|
||||||
Whether you have a specific project in mind or need help defining your requirements,
|
</h2>
|
||||||
we're here to help. Let's discuss how we can work together.
|
<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>
|
</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
|
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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue