Skip to content

Commit d973145

Browse files
committed
feat: add footer and some fixes
1 parent d491c96 commit d973145

8 files changed

Lines changed: 124 additions & 12 deletions

File tree

apps/web/www/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/mildstack-logo.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>MildStack - Free Open Source LocalStack Alternative</title>
7+
<title>MildStack: Free Open Source LocalStack Alternative</title>
88
<meta name="description" content="MildStack is a lightweight, local-first AWS emulator and LocalStack alternative. Build and test S3, DynamoDB, Lambda, SQS, and more locally with zero cloud costs and minimal overhead." />
9-
<meta name="keywords" content="aws, cloud, localsta, localstack alternative, aws emulator, local aws development, s3 local, dynamodb local, lambda local, cloud development tools, mildstack, open source aws emulator" />
9+
<meta name="keywords" content="aws, cloud, localstack, localstack alternative, aws emulator, local aws development, s3 local, dynamodb local, lambda local, sqs local, cloud development tools, s3, sqs, dynamodb, lambda, local mildstack, mildstack, open source aws emulator, ministack" />
1010

1111
<!-- Open Graph / Facebook -->
1212
<meta property="og:type" content="website" />

apps/web/www/src/components/layout/root-layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Navbar } from '@/components/shared/navbar';
44

55
export const RootLayout: React.FC = () => {
66
return (
7-
<div className="relative min-h-screen bg-black text-white overflow-hidden flex flex-col antialised">
7+
<div className="relative min-h-screen bg-background text-white overflow-hidden flex flex-col antialised">
88
{/* Navbar Container */}
99
<div className="fixed top-0 left-0 right-0 z-50 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 pointer-events-none">
1010
{/* Enable pointer events on Navbar itself while keeping wrapper pointer-events-none so we can interact with background */}
@@ -14,7 +14,7 @@ export const RootLayout: React.FC = () => {
1414
</div>
1515

1616
{/* Page Content */}
17-
<main className="flex-1 relative w-full h-full">
17+
<main className="flex-1 relative w-full h-full bg-background">
1818
<Outlet />
1919
</main>
2020
</div>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import {
2+
Grid2X2Plus,
3+
} from 'lucide-react';
4+
import mildstack from '@/assets/logos/mildstack-logo-full-white.png';
5+
6+
export function Footer() {
7+
const year = new Date().getFullYear();
8+
9+
const website = [
10+
{
11+
title: 'Home',
12+
href: '#',
13+
},
14+
{
15+
title: 'Features',
16+
href: '#',
17+
},
18+
{
19+
title: 'Services',
20+
href: '#',
21+
},
22+
{
23+
title: 'Docs',
24+
href: '#',
25+
}
26+
];
27+
28+
const resources = [
29+
{
30+
title: 'Blog',
31+
href: '#',
32+
},
33+
{
34+
title: 'Help Center',
35+
href: '#',
36+
},
37+
{
38+
title: 'Contact Support',
39+
href: '#',
40+
},
41+
{
42+
title: 'Community',
43+
href: '#',
44+
},
45+
{
46+
title: 'Security',
47+
href: '#',
48+
},
49+
];
50+
51+
const socialLinks = [
52+
{
53+
icon: <Grid2X2Plus className="size-4" />,
54+
link: 'https://github.com/michasdev/mildstack',
55+
},
56+
];
57+
return (
58+
<footer className="relative">
59+
<div className="bg-[radial-gradient(35%_80%_at_30%_0%,--theme(--color-primary/.1),transparent)] mx-auto max-w-5xl md:border-x">
60+
<div className="bg-border absolute inset-x-0 h-px w-full" />
61+
<div className="grid max-w-7xl grid-cols-5 gap-6 p-4">
62+
<div className="col-span-6 flex flex-col gap-3 md:col-span-4">
63+
<a href="#" className="w-max">
64+
<img src={mildstack} alt="MildStack Logo" className="h-12" />
65+
</a>
66+
<p className="w-full text-muted-foreground max-w-xl font-mono text-sm text-balance">
67+
Mildstack: Run AWS services locally. Free, lightweight, and open-source.
68+
<br/>
69+
The definitive LocalStack alternative.
70+
</p>
71+
<div className="flex gap-2">
72+
{socialLinks.map((item, i) => (
73+
<a
74+
key={i}
75+
className="hover:bg-accent rounded-md border p-1.5"
76+
target="_blank"
77+
href={item.link}
78+
>
79+
{item.icon}
80+
</a>
81+
))}
82+
</div>
83+
</div>
84+
<div className="col-span-3 w-full md:col-span-1">
85+
<span className="text-muted-foreground mb-1 text-xs">
86+
Resources
87+
</span>
88+
<div className="flex flex-col gap-1">
89+
{website.map(({ href, title }, i) => (
90+
<a
91+
key={i}
92+
className={`w-max py-1 text-sm duration-200 hover:underline`}
93+
href={href}
94+
>
95+
{title}
96+
</a>
97+
))}
98+
</div>
99+
</div>
100+
</div>
101+
<div className="bg-border absolute inset-x-0 h-px w-full" />
102+
<div className="flex max-w-4xl flex-col justify-between gap-2 pt-2 pb-5">
103+
<p className="text-muted-foreground text-center text-sm font-light">
104+
© <a href="https://mildstack.dev">MildStack {year}</a>. MIT Licensed. <a href="https://github.com/michasdev/mildstack" target="_blank" rel="noopener noreferrer">View Repository.</a>
105+
</p>
106+
</div>
107+
</div>
108+
</footer>
109+
);
110+
}

apps/web/www/src/components/shared/navbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { motion, AnimatePresence, useScroll, useMotionValueEvent } from 'motion/
33
import { Star, Download, Menu, X } from 'lucide-react';
44
import { Button } from '@/components/ui/button';
55
import { cn } from '@/lib/utils';
6-
import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.svg'
6+
import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.png'
77

88
const NAV_LINKS = [
99
{ label: 'Home', variant: 'outline' },
@@ -85,7 +85,7 @@ export const Navbar: React.FC = () => {
8585
transition={{ duration: 0.5 }}
8686
className={cn(
8787
"px-4 backdrop-blur-3xl rounded-full py-4 flex justify-between items-center transition-all duration-300",
88-
scrolled ? 'bg-background/80 border border-white/10 shadow-2xl shadow-white/5' : 'bg-background/50'
88+
scrolled ? 'bg-background/80 border shadow-2xl shadow-white/5' : 'bg-background/50'
8989
)}
9090
>
9191
<div className="flex items-center">

apps/web/www/src/components/ui/button.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { cn } from "@/lib/utils";
88
import { Spinner } from "@/components/ui/spinner";
99

1010
export const buttonVariants = cva(
11-
"relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-loading:select-none data-loading:text-transparent sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0",
11+
"relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-loading:select-none data-loading:text-transparent sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0",
1212
{
1313
defaultVariants: {
1414
size: "default",
@@ -23,11 +23,11 @@ export const buttonVariants = cva(
2323
"icon-xl":
2424
"size-11 sm:size-10 [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
2525
"icon-xs":
26-
"size-7 rounded-md before:rounded-[calc(var(--radius-md)-1px)] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5",
26+
"size-7 rounded-md before:rounded-[inherit] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5",
2727
lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9",
2828
sm: "h-8 gap-1.5 px-[calc(--spacing(2.5)-1px)] sm:h-7",
2929
xl: "h-11 px-[calc(--spacing(4)-1px)] text-lg sm:h-10 sm:text-base [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
30-
xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[calc(var(--radius-md)-1px)] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5",
30+
xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[inherit] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5",
3131
},
3232
variant: {
3333
default:

apps/web/www/src/features/home/components/call-to-action.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button";
33

44
export function CallToAction() {
55
return (
6-
<div className="relative mx-auto flex w-full max-w-3xl flex-col justify-between gap-y-6 border-y bg-background bg-[radial-gradient(35%_80%_at_25%_0%,color-mix(in_oklab,var(--color-primary)_35%,var(--color-background)),transparent)] px-4 py-8">
6+
<div className="relative mx-auto flex w-full max-w-3xl flex-col justify-between gap-y-6 border-y bg-background bg-[radial-gradient(35%_80%_at_75%_0%,color-mix(in_oklab,var(--color-primary)_35%,var(--color-background)),transparent)] px-4 py-8">
77
<PlusIcon
88
className="absolute top-[-12.5px] left-[-11.5px] z-1 size-6"
99
strokeWidth={1}

apps/web/www/src/features/home/home.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ import { BGPattern } from "@/components/shared/bg-pattern"
22
import { CallToAction } from "./components/call-to-action"
33
import { Features } from "./sections/features/features"
44
import { HeroSection } from "./sections/hero/hero"
5+
import { Footer } from "@/components/shared/footer"
56

67

78
const HomePage = () => {
89
return (
910
<>
1011
<HeroSection />
11-
<div className="relative isolate w-full h-full max-w-7xl mx-auto">
12+
<div className="relative isolate w-full h-full max-w-7xl mx-auto py-12 pb-40">
1213
<BGPattern variant="dots" mask="fade-x" />
1314
<Features />
1415
<CallToAction />
1516
</div>
17+
<Footer />
1618
</>
1719
)
1820
}

apps/web/www/src/features/home/sections/hero/hero.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ export const HeroSection: React.FC = () => {
318318
variants={itemVariants}
319319
className="text-center text-gray-400 mb-9 max-w-2xl leading-relaxed font-light"
320320
>
321-
High-performance and lightweight local AWS emulator for <span className="font-normal text-foreground">S3</span>, <span className="font-normal text-foreground">DynamoDB</span>, <span className="font-normal text-foreground">SQS</span>, and more. Includes an intuitive <span className="font-normal text-foreground">Desktop App</span> to manage and browse your local cloud resources from a single place.
321+
High-performance and lightweight local AWS emulator for <span className="font-normal text-foreground">S3</span>, <span className="font-normal text-foreground">DynamoDB</span>, <span className="font-normal text-foreground">SQS</span>, and more. Includes an intuitive <span className="font-normal text-foreground">Desktop App</span> to manage and browse your local cloud resources from a single place. No docker required!
322322
</motion.p>
323323
</motion.div>
324324

0 commit comments

Comments
 (0)