enh
This commit is contained in:
parent
372d9c477f
commit
d216a2d408
17 changed files with 6854 additions and 0 deletions
11
astro.config.mjs
Normal file
11
astro.config.mjs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import react from '@astrojs/react';
|
||||||
|
import tailwind from '@astrojs/tailwind';
|
||||||
|
|
||||||
|
// https://astro.build/config
|
||||||
|
export default defineConfig({
|
||||||
|
integrations: [react(), tailwind()],
|
||||||
|
output: 'static',
|
||||||
|
outDir: './dist',
|
||||||
|
site: 'https://cozy-cafe-menu.pages.dev',
|
||||||
|
});
|
||||||
6338
package-lock.json
generated
Normal file
6338
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
25
package.json
Normal file
25
package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "cozy-cafe-menu",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/react": "^3.6.3",
|
||||||
|
"@astrojs/tailwind": "^5.1.3",
|
||||||
|
"astro": "^4.16.18",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
|
"tailwindcss": "^3.4.17",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"tailwind-merge": "^2.6.0",
|
||||||
|
"lucide-react": "^0.460.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.7.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
public/favicon.svg
Normal file
3
public/favicon.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||||
|
<text y="24" font-size="24">☕</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 108 B |
BIN
public/mascot.jpeg
Normal file
BIN
public/mascot.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
BIN
public/mascot.png
Normal file
BIN
public/mascot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
BIN
public/mascot_f.png
Normal file
BIN
public/mascot_f.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 152 KiB |
41
src/components/MenuItem.tsx
Normal file
41
src/components/MenuItem.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
interface MenuItemProps {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
price: string;
|
||||||
|
image: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MenuItem({ name, description, price, image }: MenuItemProps) {
|
||||||
|
return (
|
||||||
|
<div className="group bg-white rounded-2xl overflow-hidden shadow-md hover:shadow-xl hover:shadow-sky-200/50 transition-all duration-300 hover:-translate-y-1 border-2 border-transparent hover:border-sky-300">
|
||||||
|
<div className="relative h-48 overflow-hidden">
|
||||||
|
<img
|
||||||
|
src={image}
|
||||||
|
alt={name}
|
||||||
|
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||||
|
/>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-t from-black/30 to-transparent" />
|
||||||
|
<div className="absolute top-3 right-3">
|
||||||
|
<span className="px-2 py-1 bg-sky-500 text-white text-xs font-medium rounded-lg">
|
||||||
|
Best Seller
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="p-5">
|
||||||
|
<div className="flex justify-between items-start gap-3 mb-2">
|
||||||
|
<h3 className="text-lg font-serif font-semibold text-sky-700">
|
||||||
|
{name}
|
||||||
|
</h3>
|
||||||
|
<span className="text-lg font-bold text-sky-500 whitespace-nowrap bg-sky-50 px-3 py-1 rounded-lg">
|
||||||
|
{price}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-sky-600/70 leading-relaxed">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
34
src/components/MenuSection.tsx
Normal file
34
src/components/MenuSection.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
interface MenuSectionProps {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
subtitle: string;
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MenuSection({ id, title, subtitle, children }: MenuSectionProps) {
|
||||||
|
return (
|
||||||
|
<section
|
||||||
|
id={id}
|
||||||
|
className="py-16 scroll-mt-32"
|
||||||
|
>
|
||||||
|
<div className="max-w-6xl mx-auto px-4">
|
||||||
|
<div className="text-center mb-12">
|
||||||
|
<div className="inline-block px-4 py-1 bg-sky-100 rounded-lg mb-4">
|
||||||
|
<span className="text-sky-600 text-sm font-medium">★ Featured</span>
|
||||||
|
</div>
|
||||||
|
<h2 className="text-3xl md:text-4xl font-serif font-bold text-sky-700 mb-3">
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<p className="text-sky-600/70 max-w-2xl mx-auto">
|
||||||
|
{subtitle}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
94
src/components/Navigation.tsx
Normal file
94
src/components/Navigation.tsx
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
const sections = [
|
||||||
|
{ id: 'milkshakes', label: 'Milkshakes' },
|
||||||
|
{ id: 'mocktails', label: 'Mocktails' },
|
||||||
|
{ id: 'waffles', label: 'Waffles' },
|
||||||
|
{ id: 'fries', label: 'Fries' },
|
||||||
|
{ id: 'nuggets', label: 'Nuggets' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function Navigation() {
|
||||||
|
const [activeSection, setActiveSection] = useState('milkshakes');
|
||||||
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
setIsScrolled(window.scrollY > 100);
|
||||||
|
|
||||||
|
// Find which section is currently in view
|
||||||
|
const sectionElements = sections.map(section => ({
|
||||||
|
id: section.id,
|
||||||
|
element: document.getElementById(section.id),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const scrollPosition = window.scrollY + 200;
|
||||||
|
|
||||||
|
for (let i = sectionElements.length - 1; i >= 0; i--) {
|
||||||
|
const section = sectionElements[i];
|
||||||
|
if (section.element) {
|
||||||
|
const offsetTop = section.element.offsetTop;
|
||||||
|
if (scrollPosition >= offsetTop) {
|
||||||
|
setActiveSection(section.id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
return () => window.removeEventListener('scroll', handleScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const scrollToSection = (sectionId: string) => {
|
||||||
|
const element = document.getElementById(sectionId);
|
||||||
|
if (element) {
|
||||||
|
const offsetTop = element.offsetTop - 120;
|
||||||
|
window.scrollTo({
|
||||||
|
top: offsetTop,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<nav
|
||||||
|
className={cn(
|
||||||
|
'fixed top-0 left-0 right-0 z-50 transition-all duration-300 ease-in-out',
|
||||||
|
isScrolled
|
||||||
|
? 'bg-sky-50/95 backdrop-blur-md shadow-lg py-3'
|
||||||
|
: 'bg-transparent py-6'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="max-w-6xl mx-auto px-4">
|
||||||
|
<div className="flex flex-col items-center gap-4">
|
||||||
|
{isScrolled && (
|
||||||
|
<h1 className="text-xl font-serif font-bold text-red-600">
|
||||||
|
Mr Cool
|
||||||
|
</h1>
|
||||||
|
)}
|
||||||
|
<div className="w-full overflow-x-auto scrollbar-hide">
|
||||||
|
<div className="flex gap-2 px-4 py-1 min-w-max justify-center">
|
||||||
|
{sections.map((section) => (
|
||||||
|
<button
|
||||||
|
key={section.id}
|
||||||
|
onClick={() => scrollToSection(section.id)}
|
||||||
|
className={cn(
|
||||||
|
'px-5 py-2 rounded-lg text-sm font-medium transition-all duration-200',
|
||||||
|
'hover:scale-105 active:scale-95 whitespace-nowrap',
|
||||||
|
activeSection === section.id
|
||||||
|
? 'bg-sky-500 text-white shadow-md'
|
||||||
|
: 'bg-white/80 text-sky-700 hover:bg-sky-100'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{section.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
}
|
||||||
1
src/env.d.ts
vendored
Normal file
1
src/env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
26
src/layouts/Layout.astro
Normal file
26
src/layouts/Layout.astro
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="icon" type="image/png" href="/mascot.png" />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<meta name="description" content="Mr Cool - Digital Menu. Handcrafted milkshakes, refreshing mocktails, and delicious comfort food." />
|
||||||
|
<title>{title}</title>
|
||||||
|
</head>
|
||||||
|
<body class="bg-sky-100 min-h-screen">
|
||||||
|
<slot />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
@import '../styles/globals.css';
|
||||||
|
</style>
|
||||||
6
src/lib/utils.ts
Normal file
6
src/lib/utils.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { type ClassValue, clsx } from 'clsx';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
206
src/pages/index.astro
Normal file
206
src/pages/index.astro
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro';
|
||||||
|
import { Navigation } from '../components/Navigation';
|
||||||
|
import { MenuSection } from '../components/MenuSection';
|
||||||
|
import { MenuItem } from '../components/MenuItem';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Mr Cool - Digital Menu">
|
||||||
|
<Navigation client:load />
|
||||||
|
|
||||||
|
<!-- Hero Section -->
|
||||||
|
<header class="min-h-screen w-full flex items-center justify-center bg-gradient-to-b from-sky-100 to-sky-50 px-4 pt-36">
|
||||||
|
<div class="max-w-7xl w-full grid grid-cols-1 md:grid-cols-2 gap-8 items-center">
|
||||||
|
<!-- Left: Text Content -->
|
||||||
|
<div class="text-center md:text-left">
|
||||||
|
<div class="mb-6">
|
||||||
|
<span class="inline-block px-4 py-2 bg-sky-500 text-white text-sm font-medium rounded-lg mb-4">
|
||||||
|
Welcome to
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-5xl md:text-7xl font-serif font-bold text-red-600 mb-6 leading-tight">
|
||||||
|
Mr Cool
|
||||||
|
</h1>
|
||||||
|
<p class="text-lg md:text-xl text-gray-700 mb-8 leading-relaxed">
|
||||||
|
Where every sip and bite feels like a warm hug.
|
||||||
|
Indulge in our handcrafted milkshakes, refreshing mocktails,
|
||||||
|
and delicious comfort food.
|
||||||
|
</p>
|
||||||
|
<div class="flex flex-col sm:flex-row gap-4 justify-center md:justify-start">
|
||||||
|
<a
|
||||||
|
href="#milkshakes"
|
||||||
|
class="px-8 py-4 bg-sky-500 text-white font-medium rounded-lg hover:bg-sky-600 transition-colors shadow-lg hover:shadow-xl"
|
||||||
|
>
|
||||||
|
View Menu
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right: Mascot -->
|
||||||
|
<div class="flex justify-center md:justify-end">
|
||||||
|
<img
|
||||||
|
src="/mascot.png"
|
||||||
|
alt="Mr Cool Mascot"
|
||||||
|
class="w-[410px] h-[410px] md:w-[614px] md:h-[614px] object-contain drop-shadow-2xl hover:scale-105 transition-transform duration-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Milkshakes Section -->
|
||||||
|
<MenuSection
|
||||||
|
id="milkshakes"
|
||||||
|
title="Signature Milkshakes"
|
||||||
|
subtitle="Creamy, dreamy, and made with love. Our milkshakes are blended to perfection with premium ingredients."
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
name="Kitkat Shake"
|
||||||
|
description="Rich chocolate shake blended with crushed Kitkat pieces, topped with whipped cream and more Kitkat chunks."
|
||||||
|
price="₹149"
|
||||||
|
image="https://images.unsplash.com/photo-1572490122747-3968b75cc699?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Vanilla Shake"
|
||||||
|
description="Classic creamy vanilla milkshake made with Madagascar vanilla beans and premium ice cream."
|
||||||
|
price="₹129"
|
||||||
|
image="https://images.unsplash.com/photo-1579954115545-a95591f28bfc?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Oreo Shake"
|
||||||
|
description="Cookie lover's dream! Blended with Oreo cookies, vanilla ice cream, and topped with cookie crumbles."
|
||||||
|
price="₹149"
|
||||||
|
image="https://images.unsplash.com/photo-1563805042-7684c019e1cb?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Pista Shake"
|
||||||
|
description="Delicate pistachio milkshake with real pistachio paste, garnished with crushed pistachios."
|
||||||
|
price="₹159"
|
||||||
|
image="https://images.unsplash.com/photo-1577805947697-89e18249d767?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Black Currant Shake"
|
||||||
|
description="Tangy and sweet black currant milkshake with fresh berries and a swirl of berry syrup."
|
||||||
|
price="₹149"
|
||||||
|
image="https://images.unsplash.com/photo-1623065422902-30a2d299bbe4?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
</MenuSection>
|
||||||
|
|
||||||
|
<!-- Mocktails Section -->
|
||||||
|
<MenuSection
|
||||||
|
id="mocktails"
|
||||||
|
title="Refreshing Mocktails"
|
||||||
|
subtitle="Non-alcoholic beverages crafted with fresh ingredients and bursting with flavors."
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
name="Blue Curacao"
|
||||||
|
description="Vibrant blue mocktail with citrus notes, lemonade, and a splash of soda. Refreshing and Instagram-worthy!"
|
||||||
|
price="₹119"
|
||||||
|
image="https://images.unsplash.com/photo-1513558161293-cdaf765ed2fd?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Mint Mojito"
|
||||||
|
description="Fresh mint leaves muddled with lime juice, simple syrup, and topped with soda water. Classic and refreshing."
|
||||||
|
price="₹99"
|
||||||
|
image="https://images.unsplash.com/photo-1551538827-9c037cb4f32a?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Ginger Sparkle"
|
||||||
|
description="Spicy ginger beer with fresh lime, honey, and a hint of mint. Perfect for ginger lovers."
|
||||||
|
price="₹109"
|
||||||
|
image="https://images.unsplash.com/photo-1513558161293-cdaf765ed2fd?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
</MenuSection>
|
||||||
|
|
||||||
|
<!-- Waffles Section -->
|
||||||
|
<MenuSection
|
||||||
|
id="waffles"
|
||||||
|
title="Belgian Waffles"
|
||||||
|
subtitle="Golden, crispy on the outside, fluffy on the inside. Our waffles are made fresh to order."
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
name="Classic Waffle"
|
||||||
|
description="Traditional Belgian waffle served with maple syrup and a dollop of whipped butter."
|
||||||
|
price="₹129"
|
||||||
|
image="https://images.unsplash.com/photo-1562376552-0d160a2f238d?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Chocolate Waffle"
|
||||||
|
description="Waffle topped with rich chocolate sauce, chocolate chips, and vanilla ice cream."
|
||||||
|
price="₹159"
|
||||||
|
image="https://images.unsplash.com/photo-1504754524776-8f4f37790ca0?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Berry Waffle"
|
||||||
|
description="Fresh strawberries and blueberries with honey drizzle and powdered sugar."
|
||||||
|
price="₹169"
|
||||||
|
image="https://images.unsplash.com/photo-1506084868236-b838e4ac5bd5?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
</MenuSection>
|
||||||
|
|
||||||
|
<!-- Fries Section -->
|
||||||
|
<MenuSection
|
||||||
|
id="fries"
|
||||||
|
title="French Fries"
|
||||||
|
subtitle="Crispy, golden, and absolutely addictive. Perfect for sharing or keeping all to yourself!"
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
name="Classic Fries"
|
||||||
|
description="Crispy golden fries lightly salted. The perfect side to any meal."
|
||||||
|
price="₹79"
|
||||||
|
image="https://images.unsplash.com/photo-1630384060421-cb20d0e0649d?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Cheese Fries"
|
||||||
|
description="Fries loaded with melted cheese sauce and sprinkled with herbs."
|
||||||
|
price="₹109"
|
||||||
|
image="https://images.unsplash.com/photo-1585109649139-366815a0d713?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Peri Peri Fries"
|
||||||
|
description="Spicy peri peri seasoned fries with a kick. Served with cooling dip."
|
||||||
|
price="₹99"
|
||||||
|
image="https://images.unsplash.com/photo-1573080496219-bb080dd4f877?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
</MenuSection>
|
||||||
|
|
||||||
|
<!-- Nuggets Section -->
|
||||||
|
<MenuSection
|
||||||
|
id="nuggets"
|
||||||
|
title="Chicken Nuggets"
|
||||||
|
subtitle="Tender, juicy, and perfectly crispy. Our nuggets are a crowd favorite."
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
name="Classic Nuggets"
|
||||||
|
description="6 pieces of crispy chicken nuggets served with ketchup and mustard."
|
||||||
|
price="₹129"
|
||||||
|
image="https://images.unsplash.com/photo-1626082927389-6cd097cdc6ec?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Spicy Nuggets"
|
||||||
|
description="6 pieces of spicy chicken nuggets with a fiery coating. Served with cooling ranch."
|
||||||
|
price="₹139"
|
||||||
|
image="https://images.unsplash.com/photo-1619881590738-a111d176d936?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
<MenuItem
|
||||||
|
name="Nugget Combo"
|
||||||
|
description="8 pieces with fries and a drink. The perfect meal deal!"
|
||||||
|
price="₹199"
|
||||||
|
image="https://images.unsplash.com/photo-1626082927389-6cd097cdc6ec?w=600&h=400&fit=crop"
|
||||||
|
/>
|
||||||
|
</MenuSection>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="bg-sky-900 text-white py-12 mt-16">
|
||||||
|
<div class="max-w-6xl mx-auto px-4 text-center">
|
||||||
|
<h2 class="text-2xl font-serif font-bold mb-4 text-red-500">Mr Cool</h2>
|
||||||
|
<p class="text-sky-200 mb-6 max-w-md mx-auto">
|
||||||
|
Thank you for visiting our digital menu. We can't wait to serve you in person!
|
||||||
|
</p>
|
||||||
|
<div class="border-t border-sky-700 pt-6">
|
||||||
|
<p class="text-sm text-sky-300">
|
||||||
|
© 2024 Mr Cool. All rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</Layout>
|
||||||
32
src/styles/globals.css
Normal file
32
src/styles/globals.css
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Lora:wght@400;500;600;700&family=Montserrat:wght@300;400;500;600;700&display=swap');
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Montserrat', system-ui, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: 'Lora', Georgia, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.text-balance {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-hide {
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-hide::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
tailwind.config.mjs
Normal file
24
tailwind.config.mjs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
cozy: {
|
||||||
|
cream: '#F0F9FF',
|
||||||
|
beige: '#E0F2FE',
|
||||||
|
brown: '#0EA5E9',
|
||||||
|
dark: '#0369A1',
|
||||||
|
accent: '#38BDF8',
|
||||||
|
soft: '#BAE6FD',
|
||||||
|
red: '#DC2626',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
serif: ['Lora', 'Georgia', 'serif'],
|
||||||
|
sans: ['Montserrat', 'system-ui', 'sans-serif'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
||||||
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react",
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"],
|
||||||
|
"@/components/*": ["./src/components/*"],
|
||||||
|
"@/lib/*": ["./src/lib/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue