Skip to content

Commit d8f3461

Browse files
Merge pull request #14 from fastapi-startkit/use-lucid-icons
feat: lucid icons
2 parents a0e4793 + 574c8e0 commit d8f3461

8 files changed

Lines changed: 72 additions & 53 deletions

File tree

.vitepress/theme/components/CoreModules.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
<script setup>
2+
import { Globe, Terminal, Activity, CircleCheck } from 'lucide-vue-next'
3+
</script>
4+
15
<template>
26
<section class="py-32 bg-surface">
37
<div class="max-w-7xl mx-auto px-10">
@@ -11,18 +15,18 @@
1115
<div class="bg-white p-10 flex flex-col gap-8 border-r border-outline-variant hover:bg-brand-teal/[0.02] transition-colors group">
1216
<div class="space-y-4">
1317
<div class="w-10 h-10 bg-brand-teal/10 rounded flex items-center justify-center text-brand-teal group-hover:scale-110 transition-transform">
14-
<span class="material-symbols-outlined">api</span>
18+
<Globe :size="20" />
1519
</div>
1620
<h3 class="font-headline-md text-headline-md font-semibold text-on-surface tracking-[-0.01em]">Asynchronous Core</h3>
1721
<p class="text-body-sm font-body-sm text-on-surface-variant">Fully async stack built on FastAPI, Starlette, Pydantic, and Masonite ORM — providing the fastest possible execution path for Python web applications.</p>
1822
</div>
1923
<div class="mt-auto space-y-3">
2024
<div class="flex items-center gap-3 py-2 border-t border-outline-variant/50">
21-
<span class="text-brand-teal material-symbols-outlined text-sm">check_circle</span>
25+
<CircleCheck :size="16" class="text-brand-teal" />
2226
<span class="text-label-sm font-label-sm text-on-surface">Automatic OpenAPI Docs</span>
2327
</div>
2428
<div class="flex items-center gap-3 py-2 border-t border-outline-variant/50">
25-
<span class="text-brand-teal material-symbols-outlined text-sm">check_circle</span>
29+
<CircleCheck :size="16" class="text-brand-teal" />
2630
<span class="text-label-sm font-label-sm text-on-surface">Strict Typing Engine</span>
2731
</div>
2832
</div>
@@ -32,7 +36,7 @@
3236
<div class="bg-white p-10 flex flex-col gap-8 border-r border-outline-variant hover:bg-brand-teal/[0.02] transition-colors group">
3337
<div class="space-y-4">
3438
<div class="w-10 h-10 bg-brand-teal/10 rounded flex items-center justify-center text-brand-teal group-hover:scale-110 transition-transform">
35-
<span class="material-symbols-outlined">terminal</span>
39+
<Terminal :size="20" />
3640
</div>
3741
<h3 class="font-headline-md text-headline-md font-semibold text-on-surface tracking-[-0.01em]">Artisan CLI</h3>
3842
<p class="text-body-sm font-body-sm text-on-surface-variant">Powerful artisan commands for scaffolding models, running migrations, seeding databases, and managing your application — all from the terminal.</p>
@@ -51,7 +55,7 @@
5155
<div class="bg-white p-10 flex flex-col gap-8 hover:bg-brand-teal/[0.02] transition-colors group">
5256
<div class="space-y-4">
5357
<div class="w-10 h-10 bg-brand-teal/10 rounded flex items-center justify-center text-brand-teal group-hover:scale-110 transition-transform">
54-
<span class="material-symbols-outlined">monitoring</span>
58+
<Activity :size="20" />
5559
</div>
5660
<h3 class="font-headline-md text-headline-md font-semibold text-on-surface tracking-[-0.01em]">Observability Stack</h3>
5761
<p class="text-body-sm font-body-sm text-on-surface-variant">Native integration with Prometheus, Grafana, and OpenTelemetry for deep inspection of application state.</p>

.vitepress/theme/components/HeroSection.vue

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup>
22
import { computed, onMounted, onUnmounted, ref } from "vue"
3+
import { Terminal, FileText, Copy } from "lucide-vue-next"
34
45
// ── Raw Python snippet imports ──────────────────────────────────────────────
56
import applicationRaw from "../snippets/application.py?raw"
@@ -78,7 +79,7 @@
7879
const currentTabData = computed(() => tabData[activeCategory.value])
7980
8081
const currentCode = computed(() => {
81-
if (!highlighterReady.value) return ""
82+
if (!highlighterReady.value) return escapeHtml(currentTabData.value.raw[activeFileIndex.value])
8283
const h = highlighted.value[activeCategory.value]
8384
if (h) return h[activeFileIndex.value] ?? escapeHtml(currentTabData.value.raw[activeFileIndex.value])
8485
return escapeHtml(currentTabData.value.raw[activeFileIndex.value])
@@ -109,6 +110,20 @@
109110
isTransitioning.value = false
110111
}, 150)
111112
}
113+
114+
// ── Synchronized horizontal scroll (file tabs ↔ code body) ─────────────────
115+
const fileTabsRef = ref(null)
116+
const codeBodyRef = ref(null)
117+
118+
function onCodeScroll() {
119+
if (fileTabsRef.value && codeBodyRef.value)
120+
fileTabsRef.value.scrollLeft = codeBodyRef.value.scrollLeft
121+
}
122+
123+
function onTabsScroll() {
124+
if (fileTabsRef.value && codeBodyRef.value)
125+
codeBodyRef.value.scrollLeft = fileTabsRef.value.scrollLeft
126+
}
112127
</script>
113128
114129
<template>
@@ -149,7 +164,7 @@
149164
<div class="flex flex-col sm:flex-row gap-4">
150165
<a href="/docs/getting-started" class="bg-brand-teal text-white px-8 py-4 rounded font-label-md font-bold flex items-center justify-center gap-2 transition-all hover:brightness-110 shadow-lg shadow-brand-teal/20 active:scale-[0.98]">
151166
Initialize Project
152-
<span class="material-symbols-outlined text-[18px]">terminal</span>
167+
<Terminal :size="18" />
153168
</a>
154169
</div>
155170
@@ -192,34 +207,34 @@
192207
193208
<!-- Chrome bar -->
194209
<div class="flex items-center justify-between px-4 py-3 bg-editor-chrome border-b border-brand-teal/10">
195-
<div class="flex items-center gap-6">
210+
<div class="flex items-center gap-6 min-w-0 flex-1 overflow-hidden">
196211
<!-- Traffic lights -->
197-
<div class="flex gap-1.5">
212+
<div class="flex gap-1.5 shrink-0">
198213
<div class="w-3 h-3 rounded-full bg-[#ff5f56]"></div>
199214
<div class="w-3 h-3 rounded-full bg-[#ffbd2e]"></div>
200215
<div class="w-3 h-3 rounded-full bg-[#27c93f]"></div>
201216
</div>
202217
<!-- File tabs -->
203-
<div class="flex gap-4">
218+
<div ref="fileTabsRef" class="flex gap-4 overflow-x-auto scrollbar-none min-w-0 flex-1" @scroll="onTabsScroll">
204219
<button
205220
v-for="(file, idx) in currentTabData.files"
206221
:key="file"
207-
class="px-3 py-1 flex items-center gap-2 rounded transition-all"
222+
class="px-3 py-1 flex items-center gap-2 rounded transition-all shrink-0"
208223
:class="activeFileIndex === idx ? 'bg-brand-teal/10 border-b-2 border-brand-teal' : 'opacity-50 hover:opacity-75'"
209224
@click="switchFile(idx)"
210225
>
211-
<span class="material-symbols-outlined text-xs" :class="activeFileIndex === idx ? 'text-brand-teal' : 'text-outline-variant'">description</span>
226+
<FileText :size="12" :class="activeFileIndex === idx ? 'text-brand-teal' : 'text-outline-variant'" />
212227
<span class="text-xs font-mono tracking-tight" :class="activeFileIndex === idx ? 'text-white' : 'text-outline-variant'">{{ file }}</span>
213228
</button>
214229
</div>
215230
</div>
216-
<span class="material-symbols-outlined text-outline-variant text-sm hover:text-brand-teal cursor-pointer transition-colors">content_copy</span>
231+
<Copy :size="14" class="text-outline-variant hover:text-brand-teal cursor-pointer transition-colors" />
217232
</div>
218233
219234
<!-- Code body -->
220-
<div class="p-6 md:p-8 font-mono text-[13px] leading-relaxed h-[410px] overflow-y-auto overflow-x-hidden">
235+
<div ref="codeBodyRef" class="p-6 md:p-8 font-mono text-[13px] leading-relaxed h-[410px] overflow-y-auto overflow-x-auto" @scroll="onCodeScroll">
221236
<pre
222-
class="text-white transition-all duration-200 m-0 p-0 bg-transparent"
237+
class="text-white transition-all duration-200 m-0 p-0 bg-transparent whitespace-pre"
223238
:class="{ 'opacity-0 translate-y-1': isTransitioning }"
224239
><code v-html="currentCode" class="bg-transparent"></code></pre>
225240
</div>

.vitepress/theme/components/PerformanceBenchmarks.vue

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
<script setup>
2+
import { Gauge, Shield, ArrowRight } from 'lucide-vue-next'
3+
</script>
4+
15
<template>
26
<section class="relative bg-inverse-surface text-white py-32 overflow-hidden">
37
<!-- Background effects -->
@@ -25,7 +29,7 @@
2529
<ul class="space-y-8">
2630
<li class="flex items-start gap-6 group/item">
2731
<div class="mt-1 w-10 h-10 rounded bg-brand-teal/10 border border-brand-teal/20 flex items-center justify-center shrink-0 group-hover/item:bg-brand-teal/30 transition-colors">
28-
<span class="material-symbols-outlined text-brand-teal">speed</span>
32+
<Gauge :size="20" class="text-brand-teal" />
2933
</div>
3034
<div class="space-y-1">
3135
<h4 class="font-headline-md text-headline-md font-semibold text-white tracking-[-0.01em]">Zero-copy Processing</h4>
@@ -34,7 +38,7 @@
3438
</li>
3539
<li class="flex items-start gap-6 group/item">
3640
<div class="mt-1 w-10 h-10 rounded bg-brand-teal/10 border border-brand-teal/20 flex items-center justify-center shrink-0 group-hover/item:bg-brand-teal/30 transition-colors">
37-
<span class="material-symbols-outlined text-brand-teal">shield</span>
41+
<Shield :size="20" class="text-brand-teal" />
3842
</div>
3943
<div class="space-y-1">
4044
<h4 class="font-headline-md text-headline-md font-semibold text-white tracking-[-0.01em]">Encrypted Pipelines</h4>
@@ -94,7 +98,7 @@
9498
<div class="mt-14 pt-8 border-t border-white/10">
9599
<button class="w-full text-brand-teal font-label-sm text-[10px] uppercase tracking-[0.2em] hover:text-white transition-colors flex items-center justify-center gap-2 group/btn">
96100
View Technical Methodology
97-
<span class="material-symbols-outlined text-sm group-hover/btn:translate-x-1 transition-transform">arrow_forward</span>
101+
<ArrowRight :size="14" class="group-hover/btn:translate-x-1 transition-transform" />
98102
</button>
99103
</div>
100104
</div>

.vitepress/theme/components/SiteFooter.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script setup>
2+
import { Terminal } from 'lucide-vue-next'
23
const startYear = 2026
34
const currentYear = new Date().getFullYear()
45
const copyrightYear = currentYear > startYear ? `${startYear}${currentYear}` : `${startYear}`
@@ -9,7 +10,7 @@
910
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 w-full max-w-[1280px] mx-auto py-12 px-10">
1011
<div class="space-y-4">
1112
<div class="font-label-md text-label-md font-bold text-brand-teal flex items-center gap-2">
12-
<span class="material-symbols-outlined text-brand-teal">terminal</span>
13+
<Terminal :size="18" class="text-brand-teal" />
1314
Fastapi Starkit
1415
</div>
1516
<p class="text-body-sm font-body-sm text-on-surface-variant">

.vitepress/theme/components/SiteHeader.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup>
22
import { useData } from 'vitepress'
33
import { computed } from 'vue'
4+
import { Zap, Search } from 'lucide-vue-next'
45
56
const { page } = useData()
67
const currentPath = computed(() => page.value.relativePath)
@@ -24,7 +25,7 @@ function openSearch() {
2425
<!-- Left: Logo + desktop nav links -->
2526
<div class="flex items-center gap-8 md:gap-12">
2627
<a href="/" class="font-headline-md font-bold text-brand-teal tracking-tight flex items-center gap-2 hover:opacity-90 transition-opacity shrink-0">
27-
<span class="material-symbols-outlined">bolt</span>
28+
<Zap :size="20" />
2829
<span class="hidden sm:inline">FastAPI Startkit</span>
2930
</a>
3031

@@ -47,7 +48,7 @@ function openSearch() {
4748
@click="openSearch"
4849
>
4950
<span class="text-on-surface-variant text-label-md font-label-md flex items-center gap-2">
50-
<span class="material-symbols-outlined" style="font-size:16px">search</span>
51+
<Search :size="16" />
5152
Search docs...
5253
</span>
5354
<span class="ml-4 text-[10px] text-outline font-label-sm border border-outline-variant px-1.5 py-0.5 rounded bg-white">⌘K</span>
@@ -59,7 +60,7 @@ function openSearch() {
5960
@click="openSearch"
6061
aria-label="Search"
6162
>
62-
<span class="material-symbols-outlined text-on-surface-variant" style="font-size:18px">search</span>
63+
<Search :size="18" class="text-on-surface-variant" />
6364
</button>
6465

6566
<!-- Docs link — mobile/tablet only (< md) -->

.vitepress/theme/custom.css

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Google Fonts — must precede all other statements */
2-
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500&family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap');
2+
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500&display=swap');
33

44
@import "tailwindcss";
55

@@ -89,13 +89,6 @@
8989
--text-label-sm--font-weight: 500;
9090
}
9191

92-
/* ===== Material Symbols ===== */
93-
.material-symbols-outlined {
94-
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
95-
display: inline-block;
96-
vertical-align: middle;
97-
line-height: 1;
98-
}
9992

10093
/* ===== Utility Classes ===== */
10194
.code-shadow {
@@ -186,6 +179,14 @@ h1, h2, h3, h4 {
186179
font-family: 'Geist', sans-serif;
187180
}
188181

182+
/* ===== Hide scrollbar utility ===== */
183+
.scrollbar-none {
184+
scrollbar-width: none;
185+
}
186+
.scrollbar-none::-webkit-scrollbar {
187+
display: none;
188+
}
189+
189190
/* ===== Syntax Highlighting for Code Editor ===== */
190191
.code-keyword {
191192
color: #ff7b72;

0 commit comments

Comments
 (0)