design: improved site-wide light/dark theme, home footer is looking normal again, misc tweaks
This commit is contained in:
parent
6cd5d6051f
commit
1463722a84
@ -71,10 +71,10 @@
|
|||||||
@utility container {
|
@utility container {
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
padding-inline: 2rem;
|
padding-inline: 2rem;
|
||||||
@media (width >= --theme(--breakpoint-sm)) {
|
@media (min-width: theme('screens.sm')) {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
@media (width >= 1400px) {
|
@media (min-width: 1400px) {
|
||||||
max-width: 1400px;
|
max-width: 1400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@
|
|||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 0 0% 100%;
|
--background: 30 20% 98%;
|
||||||
--foreground: 222.2 84% 4.9%;
|
--foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
--muted: 210 40% 96.1%;
|
--muted: 210 40% 96.1%;
|
||||||
@ -120,7 +120,7 @@
|
|||||||
--secondary: 210 40% 96.1%;
|
--secondary: 210 40% 96.1%;
|
||||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
--accent: 210 40% 96.1%;
|
--accent: 210 60% 95%;
|
||||||
--accent-foreground: 222.2 47.4% 11.2%;
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
--destructive: 0 84.2% 60.2%;
|
--destructive: 0 84.2% 60.2%;
|
||||||
@ -130,20 +130,13 @@
|
|||||||
|
|
||||||
--radius: 0.5rem;
|
--radius: 0.5rem;
|
||||||
|
|
||||||
--sidebar-background: 0 0% 98%;
|
--sidebar-background: 215 25% 97%;
|
||||||
|
|
||||||
--sidebar-foreground: 240 5.3% 26.1%;
|
--sidebar-foreground: 240 5.3% 26.1%;
|
||||||
|
|
||||||
--sidebar-primary: 240 5.9% 10%;
|
--sidebar-primary: 240 5.9% 10%;
|
||||||
|
|
||||||
--sidebar-primary-foreground: 0 0% 98%;
|
--sidebar-primary-foreground: 0 0% 98%;
|
||||||
|
--sidebar-accent: 215 10% 92%;
|
||||||
--sidebar-accent: 240 4.8% 95.9%;
|
|
||||||
|
|
||||||
--sidebar-accent-foreground: 240 5.9% 10%;
|
--sidebar-accent-foreground: 240 5.9% 10%;
|
||||||
|
--sidebar-border: 220 13% 88%;
|
||||||
--sidebar-border: 220 13% 91%;
|
|
||||||
|
|
||||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ export default function Home() {
|
|||||||
]
|
]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-linear-to-b from-gray-950 to-gray-900">
|
<div className="min-h-screen dark:bg-linear-to-b dark:from-gray-950 dark:to-gray-900">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main>
|
<main>
|
||||||
<Hero />
|
<Hero />
|
||||||
<section id="services">
|
<section id="services">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<h2 className="text-4xl font-extrabold text-center mb-12 text-white">Our Services</h2>
|
<h2 className="text-4xl font-extrabold text-center mb-12 text-foreground">Our Services</h2>
|
||||||
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
{features.map((feature, index) => (
|
{features.map((feature, index) => (
|
||||||
<FeatureCard key={index} {...feature} />
|
<FeatureCard key={index} {...feature} />
|
||||||
|
@ -6,7 +6,7 @@ import Link from "next/link"
|
|||||||
|
|
||||||
export default function Privacy() {
|
export default function Privacy() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-linear-to-b from-gray-950 to-gray-900">
|
<div className="min-h-screen dark:bg-linear-to-b dark:from-gray-950 dark:to-gray-900">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main>
|
<main>
|
||||||
<div className="pt-20 pb-10">
|
<div className="pt-20 pb-10">
|
||||||
|
@ -7,17 +7,20 @@ interface FeatureCardProps {
|
|||||||
icon: React.ElementType
|
icon: React.ElementType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: I plan to add a better animation in the future, hover effects are not
|
||||||
|
good here, in my opinion. */
|
||||||
|
|
||||||
const FeatureCard = ({ title, description, icon: Icon }: FeatureCardProps) => {
|
const FeatureCard = ({ title, description, icon: Icon }: FeatureCardProps) => {
|
||||||
return (
|
return (
|
||||||
<Card className="bg-gray-800 border-gray-700 hover:bg-gray-700 transition-colors duration-300">
|
<Card className="bg-background border-accent transition-colors duration-300">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center text-white">
|
<CardTitle className="flex items-center">
|
||||||
<Icon className="h-6 w-6 mr-2 text-blue-400" />
|
<Icon className="h-6 w-6 mr-2 text-blue-400" />
|
||||||
<span className="text-xl">{title}</span>
|
<span className="text-xl">{title}</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<CardDescription className="text-gray-300">{description}</CardDescription>
|
<CardDescription>{description}</CardDescription>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
)
|
||||||
|
@ -1,39 +1,48 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
import { RiOpenSourceFill } from "react-icons/ri"
|
import { RiOpenSourceFill } from "react-icons/ri"
|
||||||
import { ArrowUp } from "lucide-react"
|
import { ArrowUp } from "lucide-react"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
|
const scrollToTop = () => {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<footer className="bg-gray-200 dark:bg-gray-900 py-4 mt-auto">
|
||||||
<footer className="bg-gray-950/70">
|
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="flex flex-col items-center py-4 md:flex-row md:justify-between md:items-center">
|
<div className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4">
|
||||||
<div className="flex items-center mt-8 md:mt-0 md:order-1">
|
<div className="flex items-center justify-center sm:justify-start">
|
||||||
<RiOpenSourceFill className="text-muted-foreground mr-1" />
|
<RiOpenSourceFill className="text-gray-600 dark:text-gray-400 mr-2 text-lg" aria-hidden="true" />
|
||||||
<Link
|
<Link
|
||||||
href="https://git.pontusmail.org/librecloud/web"
|
href="https://git.pontusmail.org/librecloud/web"
|
||||||
className="text-muted-foreground hover:text-foreground transition-all"
|
className="text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"
|
||||||
|
aria-label="View source code"
|
||||||
>
|
>
|
||||||
Open Source & Public Domain
|
Open Source & Public Domain
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center space-x-6 md:order-2">
|
<div className="flex items-center justify-center space-x-6">
|
||||||
<Link
|
<Link
|
||||||
href="/privacy"
|
href="/privacy"
|
||||||
className="text-muted-foreground hover:text-foreground transition-all"
|
className="text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"
|
||||||
>
|
>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<button
|
||||||
href="#"
|
onClick={scrollToTop}
|
||||||
className="text-muted-foreground hover:text-foreground transition-all"
|
className="flex items-center justify-center p-2 rounded-full bg-gray-300 dark:bg-gray-800 text-gray-600 dark:text-gray-400 hover:bg-gray-400 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-gray-100 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-500"
|
||||||
|
aria-label="Scroll to top"
|
||||||
>
|
>
|
||||||
<ArrowUp />
|
<ArrowUp className="w-4 h-4" />
|
||||||
</Link>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ const Hero = () => {
|
|||||||
const phrases = ["everyone", "developers", "students", "non-profits", "teachers", "workers", "friends"]
|
const phrases = ["everyone", "developers", "students", "non-profits", "teachers", "workers", "friends"]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pt-20 pb-30 text-white">
|
<div className="pt-20 pb-30 text-foreground">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="text-4xl tracking-tight font-extrabold sm:text-5xl md:text-6xl">
|
<h1 className="text-4xl tracking-tight font-extrabold sm:text-5xl md:text-6xl">
|
||||||
@ -18,7 +18,7 @@ const Hero = () => {
|
|||||||
for <ReactTyped strings={phrases} typeSpeed={60} backSpeed={50} loop className="text-blue-400" />
|
for <ReactTyped strings={phrases} typeSpeed={60} backSpeed={50} loop className="text-blue-400" />
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-6 max-w-md mx-auto text-xl text-gray-300 sm:max-w-3xl">
|
<p className="mt-6 max-w-md mx-auto text-xl text-muted-foreground sm:max-w-3xl">
|
||||||
Experience FOSS at its best with LibreCloud, a free service provider built with everyone in mind.
|
Experience FOSS at its best with LibreCloud, a free service provider built with everyone in mind.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-10 max-w-md mx-auto sm:flex sm:justify-center">
|
<div className="mt-10 max-w-md mx-auto sm:flex sm:justify-center">
|
||||||
|
@ -8,12 +8,12 @@ const Navbar = () => {
|
|||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="bg-gray-950/70 sticky top-0 z-50">
|
<nav className="bg-gray-300 dark:bg-gray-950/70 sticky top-0 z-50">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="relative flex items-center justify-between h-16">
|
<div className="relative flex items-center justify-between h-16">
|
||||||
<div className="shrink-0 flex items-center">
|
<div className="shrink-0 flex items-center">
|
||||||
<Link href="/" className="flex items-center">
|
<Link href="/" className="flex items-center">
|
||||||
<span className="text-white text-xl font-bold">LibreCloud</span>
|
<span className="text-xl font-bold">LibreCloud</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden md:block">
|
<div className="hidden md:block">
|
||||||
@ -80,7 +80,7 @@ interface NavLinkProps {
|
|||||||
const NavLink: React.FC<NavLinkProps> = ({ href, icon: Icon, children }) => (
|
const NavLink: React.FC<NavLinkProps> = ({ href, icon: Icon, children }) => (
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
className="flex items-center text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200"
|
className="flex items-center hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium transition-colors duration-200"
|
||||||
>
|
>
|
||||||
<Icon className="mr-2 h-5 w-5" /> {children}
|
<Icon className="mr-2 h-5 w-5" /> {children}
|
||||||
</Link>
|
</Link>
|
||||||
@ -95,7 +95,7 @@ interface MobileNavLinkProps {
|
|||||||
const MobileNavLink: React.FC<MobileNavLinkProps> = ({ href, icon: Icon, children }) => (
|
const MobileNavLink: React.FC<MobileNavLinkProps> = ({ href, icon: Icon, children }) => (
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
className="flex items-center text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-base font-medium"
|
className="flex items-center hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-base font-medium"
|
||||||
>
|
>
|
||||||
<Icon className="mr-2 h-5 w-5" /> {children}
|
<Icon className="mr-2 h-5 w-5" /> {children}
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { RiOpenSourceFill } from "react-icons/ri";
|
import { RiOpenSourceFill } from "react-icons/ri";
|
||||||
import { Ampersand } from "lucide-react";
|
import { TbAmpersand } from "react-icons/tb";
|
||||||
import { HiMiniHeart } from "react-icons/hi2";
|
import { HiMiniHeart } from "react-icons/hi2";
|
||||||
|
|
||||||
const PoweredBySection = () => {
|
const PoweredBySection = () => {
|
||||||
@ -8,12 +8,12 @@ const PoweredBySection = () => {
|
|||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<h2 className="text-5xl md:text-6xl font-extrabold text-center mb-8 ">Powered by</h2>
|
<h2 className="text-5xl md:text-6xl font-extrabold text-center mb-8 ">Powered by</h2>
|
||||||
<div className="flex flex-col sm:flex-row justify-center items-center">
|
<div className="flex flex-col sm:flex-row justify-center items-center">
|
||||||
<div className="bg-green-400 rounded-full flex items-center p-4 lg:px-8 sm:mb-0">
|
<div className="bg-green-400 text-green-800 rounded-full flex items-center p-4 lg:px-8 sm:mb-0">
|
||||||
<RiOpenSourceFill size={40} className="my-auto mr-2 lg:size-22" />
|
<RiOpenSourceFill size={40} className="my-auto mr-2 lg:size-22" />
|
||||||
<h1 className="text-4xl lg:text-8xl font-extrabold">libre</h1>
|
<h1 className="text-4xl lg:text-8xl font-extrabold">libre</h1>
|
||||||
</div>
|
</div>
|
||||||
<Ampersand size={40} className="m-4 lg:my-8 lg:size-22" />
|
<TbAmpersand size={40} className="m-4 lg:my-8 lg:size-22" />
|
||||||
<div className="bg-red-400 rounded-full flex items-center p-4 lg:px-8">
|
<div className="bg-red-400 text-red-800 rounded-full flex items-center p-4 lg:px-8">
|
||||||
<HiMiniHeart size={40} className="my-auto mr-2 lg:size-24" />
|
<HiMiniHeart size={40} className="my-auto mr-2 lg:size-24" />
|
||||||
<h1 className="text-4xl lg:text-8xl font-extrabold">love</h1>
|
<h1 className="text-4xl lg:text-8xl font-extrabold">love</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,10 +49,10 @@ export default function Pricing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id="love" className="pt-24 pb-10">
|
<section id="pricing" className="pb-10">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="text-center mb-16">
|
<div className="text-center mb-16">
|
||||||
<h2 className="text-4xl font-extrabold text-white mb-4">Pricing You'll Love</h2>
|
<h2 className="text-4xl font-extrabold text-foreground mb-4">Pricing You'll Love</h2>
|
||||||
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
|
||||||
Simple, transparent pricing with zero additional fees.
|
Simple, transparent pricing with zero additional fees.
|
||||||
</p>
|
</p>
|
||||||
@ -60,7 +60,7 @@ export default function Pricing() {
|
|||||||
|
|
||||||
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
<div className="grid grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
<motion.div
|
<motion.div
|
||||||
className={`relative overflow-hidden rounded-xl border bg-gray-800 text-card-foreground shadow transition-all duration-300 ${hoveredCard === 0 ? "border-gray-700" : "border-border"}`}
|
className={`relative overflow-hidden rounded-xl border bg-slate-200 dark:bg-gray-800 text-card-foreground shadow transition-all duration-300 ${hoveredCard === 0 ? "border-gray-700" : "border-border"} text-background`}
|
||||||
variants={cardVariants}
|
variants={cardVariants}
|
||||||
initial="default"
|
initial="default"
|
||||||
animate={hoveredCard === 0 ? "hover" : "default"}
|
animate={hoveredCard === 0 ? "hover" : "default"}
|
||||||
@ -70,7 +70,7 @@ export default function Pricing() {
|
|||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="mb-4 flex items-center justify-between">
|
<div className="mb-4 flex items-center justify-between">
|
||||||
<h3 className="text-2xl font-bold">Everything</h3>
|
<h3 className="text-2xl font-bold">Everything</h3>
|
||||||
<Badge variant="outline" className="text-xs font-medium bg-gray-900">
|
<Badge variant="outline" className="text-xs font-medium bg-background">
|
||||||
Most Popular
|
Most Popular
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
@ -78,8 +78,8 @@ export default function Pricing() {
|
|||||||
<span className="text-6xl font-bold">$0.00</span>
|
<span className="text-6xl font-bold">$0.00</span>
|
||||||
<span className="text-muted-foreground ml-2">/mo</span>
|
<span className="text-muted-foreground ml-2">/mo</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-muted-foreground mb-6">
|
<p className="text-sm text-secondary-foreground mb-6">
|
||||||
All the essential services you need, completely free.
|
All the services we offer, completely free.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/account/login">
|
<Link href="/account/login">
|
||||||
<Button className="w-full" size="lg">
|
<Button className="w-full" size="lg">
|
||||||
@ -87,7 +87,8 @@ export default function Pricing() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
{/* TODO: this seperator be improved in the future, i can't find a good color for this */}
|
||||||
|
<Separator className="bg-gray-700" />
|
||||||
<div className="p-6 space-y-4">
|
<div className="p-6 space-y-4">
|
||||||
<h4 className="text-sm font-medium">What's included:</h4>
|
<h4 className="text-sm font-medium">What's included:</h4>
|
||||||
<div>
|
<div>
|
||||||
@ -149,7 +150,7 @@ export default function Pricing() {
|
|||||||
<span className="text-6xl font-bold">$0.00</span>
|
<span className="text-6xl font-bold">$0.00</span>
|
||||||
<span className="text-muted-foreground ml-2">/M tokens</span>
|
<span className="text-muted-foreground ml-2">/M tokens</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-muted-foreground mb-6">Access powerful AI models at cost price.</p>
|
<p className="text-sm text-muted-foreground mb-6">Access powerful AI models at the best price.</p>
|
||||||
<Button className="w-full" size="lg" variant="outline" disabled>
|
<Button className="w-full" size="lg" variant="outline" disabled>
|
||||||
<Clock /> Coming Soon
|
<Clock /> Coming Soon
|
||||||
</Button>
|
</Button>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user