Skip to content

Commit 81eda69

Browse files
committed
feat: Add optional hero background image to tutorial pages
- Add hero_image field to tutorials schema in content config - Update TutorialLayout to conditionally render background image when specified - Position image on right 60% with gradient overlay (opaque left -> transparent right) - Add hero image to initial-setup-jetson-orin-nano tutorial as example - Background blurs reduce opacity when hero image is present Each tutorial can now optionally specify a hero_image in frontmatter to display a background image with gradient overlay, keeping text readable on the left.
1 parent 6c964f8 commit 81eda69

File tree

4 files changed

+34
-11
lines changed

4 files changed

+34
-11
lines changed
File renamed without changes.

src/content/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const tutorials = defineCollection({
1212
model: z.string().optional(),
1313
featured: z.boolean().optional(),
1414
isNew: z.boolean().optional(), // Mark as new tutorial
15+
hero_image: z.string().optional(), // Optional background image for hero section
1516
}),
1617
});
1718

src/content/tutorials/initial-setup-jetson-orin-nano.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ category: "Setup"
55
section: "Jetson Setup"
66
order: 1
77
tags: ["setup", "jetson", "orin-nano", "jetpack", "firmware", "microsd", "getting-started"]
8+
hero_image: "/images/hero/isometric_jon-devkit.png"
89
---
910

1011
> This guide supplements the official [Jetson Orin Nano Developer Kit Getting Started Guide](https://developer.nvidia.com/embedded/learn/get-started-jetson-orin-nano-devkit).

src/layouts/TutorialLayout.astro

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,45 @@ const { Content, headings } = await tutorial.render();
2020
<Layout title={tutorial.data.title} description={tutorial.data.description}>
2121
<div class="bg-white min-h-screen">
2222
<!-- Hero Section -->
23-
<div class="bg-slate-900 text-white border-b border-slate-800">
23+
<div class="bg-slate-900 text-white border-b border-slate-800 relative">
24+
{tutorial.data.hero_image && (
25+
<>
26+
<!-- Background Image with Gradient Overlay -->
27+
<div class="absolute inset-y-0 right-0 w-3/5 overflow-hidden">
28+
<img
29+
src={tutorial.data.hero_image}
30+
alt={tutorial.data.title}
31+
class="w-full h-full object-cover object-center opacity-40"
32+
/>
33+
</div>
34+
<!-- Gradient overlay: opaque left to semi-transparent right -->
35+
<div class="absolute inset-0 bg-gradient-to-r from-slate-900 via-slate-900/90 via-60% to-transparent"></div>
36+
</>
37+
)}
38+
2439
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 lg:py-24 relative overflow-hidden">
25-
<!-- Background pattern -->
26-
<div class="absolute top-0 right-0 -mt-20 -mr-20 w-96 h-96 bg-nvidia-green/10 rounded-full blur-3xl"></div>
27-
<div class="absolute bottom-0 left-0 -mb-20 -ml-20 w-80 h-80 bg-blue-500/10 rounded-full blur-3xl"></div>
28-
40+
<!-- Background pattern (subtle when image present) -->
41+
<div class:list={[
42+
"absolute top-0 right-0 -mt-20 -mr-20 w-96 h-96 rounded-full blur-3xl",
43+
tutorial.data.hero_image ? "bg-nvidia-green/5" : "bg-nvidia-green/10"
44+
]}></div>
45+
<div class:list={[
46+
"absolute bottom-0 left-0 -mb-20 -ml-20 w-80 h-80 rounded-full blur-3xl",
47+
tutorial.data.hero_image ? "bg-blue-500/5" : "bg-blue-500/10"
48+
]}></div>
49+
2950
<div class="relative z-10 max-w-3xl">
3051
<div class="flex items-center gap-4 mb-6 text-sm font-medium text-nvidia-green">
3152
<a href="/tutorials" class="hover:text-white transition-colors flex items-center gap-1">
3253
<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="M15 19l-7-7 7-7"/></svg>
3354
Back to Tutorials
3455
</a>
3556
</div>
36-
57+
3758
<h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-6 tracking-tight leading-tight">
3859
{tutorial.data.title}
3960
</h1>
40-
61+
4162
<p class="text-xl text-slate-300 mb-8 leading-relaxed max-w-2xl">
4263
{tutorial.data.description}
4364
</p>
@@ -55,15 +76,15 @@ const { Content, headings } = await tutorial.render();
5576
</h3>
5677
<nav class="space-y-1">
5778
{headings.filter(h => h.depth <= 2).map((heading) => (
58-
<a
79+
<a
5980
href={`#${heading.slug}`}
6081
class="block py-1.5 text-sm text-slate-600 hover:text-nvidia-green hover:pl-1 transition-all duration-200 border-l-2 border-transparent hover:border-nvidia-green pl-3 -ml-3"
6182
>
6283
{heading.text}
6384
</a>
6485
))}
6586
</nav>
66-
87+
6788
<div class="mt-8 pt-8 border-t border-slate-200">
6889
<h3 class="text-sm font-semibold text-slate-900 uppercase tracking-wider mb-4">
6990
Resources
@@ -84,7 +105,7 @@ const { Content, headings } = await tutorial.render();
84105

85106
<!-- Main Content -->
86107
<main class="lg:col-span-9">
87-
<div class="prose prose-slate prose-lg max-w-none
108+
<div class="prose prose-slate prose-lg max-w-none
88109
prose-headings:font-bold prose-headings:tracking-tight prose-headings:text-slate-900
89110
prose-p:text-slate-600 prose-p:leading-relaxed
90111
prose-a:text-nvidia-green prose-a:no-underline hover:prose-a:underline
@@ -126,7 +147,7 @@ const { Content, headings } = await tutorial.render();
126147
:global(.prose h2), :global(.prose h3) {
127148
position: relative;
128149
}
129-
150+
130151
html {
131152
scroll-behavior: smooth;
132153
scroll-padding-top: 100px;

0 commit comments

Comments
 (0)