Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/web/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/mildstack-logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MildStack - Free Open Source LocalStack Alternative</title>
<title>MildStack: Free Open Source LocalStack Alternative</title>
<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." />
<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" />
<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" />

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
Expand Down
4 changes: 2 additions & 2 deletions apps/web/www/src/components/layout/root-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Navbar } from '@/components/shared/navbar';

export const RootLayout: React.FC = () => {
return (
<div className="relative min-h-screen bg-black text-white overflow-hidden flex flex-col antialised">
<div className="relative min-h-screen bg-background text-white overflow-hidden flex flex-col antialised">
{/* Navbar Container */}
<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">
{/* Enable pointer events on Navbar itself while keeping wrapper pointer-events-none so we can interact with background */}
Expand All @@ -14,7 +14,7 @@ export const RootLayout: React.FC = () => {
</div>

{/* Page Content */}
<main className="flex-1 relative w-full h-full">
<main className="flex-1 relative w-full h-full bg-background">
<Outlet />
</main>
</div>
Expand Down
110 changes: 110 additions & 0 deletions apps/web/www/src/components/shared/footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {
Grid2X2Plus,
} from 'lucide-react';
import mildstack from '@/assets/logos/mildstack-logo-full-white.png';

export function Footer() {
const year = new Date().getFullYear();

const website = [
{
title: 'Home',
href: '#',
},
{
title: 'Features',
href: '#',
},
{
title: 'Services',
href: '#',
},
{
title: 'Docs',
href: '#',
}
];

const resources = [
{
title: 'Blog',
href: '#',
},
{
title: 'Help Center',
href: '#',
},
{
title: 'Contact Support',
href: '#',
},
{
title: 'Community',
href: '#',
},
{
title: 'Security',
href: '#',
},
];

const socialLinks = [
{
icon: <Grid2X2Plus className="size-4" />,
link: 'https://github.com/michasdev/mildstack',
},
];
return (
<footer className="relative">
<div className="bg-[radial-gradient(35%_80%_at_30%_0%,--theme(--color-primary/.1),transparent)] mx-auto max-w-5xl md:border-x">
<div className="bg-border absolute inset-x-0 h-px w-full" />
<div className="grid max-w-7xl grid-cols-5 gap-6 p-4">
<div className="col-span-6 flex flex-col gap-3 md:col-span-4">
<a href="#" className="w-max">
<img src={mildstack} alt="MildStack Logo" className="h-12" />
</a>
<p className="w-full text-muted-foreground max-w-xl font-mono text-sm text-balance">
Mildstack: Run AWS services locally. Free, lightweight, and open-source.
<br/>
The definitive LocalStack alternative.
</p>
<div className="flex gap-2">
{socialLinks.map((item, i) => (
<a
key={i}
className="hover:bg-accent rounded-md border p-1.5"
target="_blank"
href={item.link}
>
{item.icon}
</a>
))}
</div>
</div>
<div className="col-span-3 w-full md:col-span-1">
<span className="text-muted-foreground mb-1 text-xs">
Resources
</span>
<div className="flex flex-col gap-1">
{website.map(({ href, title }, i) => (
<a
key={i}
className={`w-max py-1 text-sm duration-200 hover:underline`}
href={href}
>
{title}
</a>
))}
</div>
</div>
</div>
<div className="bg-border absolute inset-x-0 h-px w-full" />
<div className="flex max-w-4xl flex-col justify-between gap-2 pt-2 pb-5">
<p className="text-muted-foreground text-center text-sm font-light">
© <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>
</p>
</div>
</div>
</footer>
);
}
4 changes: 2 additions & 2 deletions apps/web/www/src/components/shared/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { motion, AnimatePresence, useScroll, useMotionValueEvent } from 'motion/
import { Star, Download, Menu, X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.svg'
import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.png'

const NAV_LINKS = [
{ label: 'Home', variant: 'outline' },
Expand Down Expand Up @@ -85,7 +85,7 @@ export const Navbar: React.FC = () => {
transition={{ duration: 0.5 }}
className={cn(
"px-4 backdrop-blur-3xl rounded-full py-4 flex justify-between items-center transition-all duration-300",
scrolled ? 'bg-background/80 border border-white/10 shadow-2xl shadow-white/5' : 'bg-background/50'
scrolled ? 'bg-background/80 border shadow-2xl shadow-white/5' : 'bg-background/50'
)}
>
<div className="flex items-center">
Expand Down
6 changes: 3 additions & 3 deletions apps/web/www/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { cn } from "@/lib/utils";
import { Spinner } from "@/components/ui/spinner";

export const buttonVariants = cva(
"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",
"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",
{
defaultVariants: {
size: "default",
Expand All @@ -23,11 +23,11 @@ export const buttonVariants = cva(
"icon-xl":
"size-11 sm:size-10 [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
"icon-xs":
"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",
"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",
lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9",
sm: "h-8 gap-1.5 px-[calc(--spacing(2.5)-1px)] sm:h-7",
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",
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",
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",
},
variant: {
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button";

export function CallToAction() {
return (
<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">
<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">
<PlusIcon
className="absolute top-[-12.5px] left-[-11.5px] z-1 size-6"
strokeWidth={1}
Expand Down
4 changes: 3 additions & 1 deletion apps/web/www/src/features/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import { BGPattern } from "@/components/shared/bg-pattern"
import { CallToAction } from "./components/call-to-action"
import { Features } from "./sections/features/features"
import { HeroSection } from "./sections/hero/hero"
import { Footer } from "@/components/shared/footer"


const HomePage = () => {
return (
<>
<HeroSection />
<div className="relative isolate w-full h-full max-w-7xl mx-auto">
<div className="relative isolate w-full h-full max-w-7xl mx-auto py-12 pb-40">
<BGPattern variant="dots" mask="fade-x" />
<Features />
<CallToAction />
</div>
<Footer />
</>
)
}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/www/src/features/home/sections/hero/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ export const HeroSection: React.FC = () => {
variants={itemVariants}
className="text-center text-gray-400 mb-9 max-w-2xl leading-relaxed font-light"
>
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.
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!
</motion.p>
</motion.div>

Expand Down