create-rayso 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
1
|
+
// ── app/layout.tsx ────────────────────────────────────────────────────────────
|
|
2
|
+
// app/layout.tsx — make sure you have both fonts loaded
|
|
3
|
+
|
|
1
4
|
import type { Metadata } from "next";
|
|
2
5
|
import { Inter, Playfair_Display } from "next/font/google";
|
|
3
6
|
import "./globals.css";
|
|
4
7
|
|
|
5
|
-
const inter = Inter({
|
|
6
|
-
|
|
8
|
+
const inter = Inter({
|
|
9
|
+
subsets: ["latin"],
|
|
10
|
+
variable: "--font-inter",
|
|
11
|
+
display: "swap",
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const playfair = Playfair_Display({
|
|
15
|
+
subsets: ["latin"],
|
|
16
|
+
variable: "--font-playfair",
|
|
17
|
+
display: "swap",
|
|
18
|
+
});
|
|
7
19
|
|
|
8
20
|
export const metadata: Metadata = {
|
|
9
|
-
title: "
|
|
10
|
-
description: "A premium
|
|
21
|
+
title: "Meridian — Luxury Resort",
|
|
22
|
+
description: "A premium resort experience.",
|
|
11
23
|
};
|
|
12
24
|
|
|
13
25
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
@@ -18,4 +30,4 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
18
30
|
</body>
|
|
19
31
|
</html>
|
|
20
32
|
);
|
|
21
|
-
}
|
|
33
|
+
}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
// ── app/page.tsx ──────────────────────────────────────────────────────────────
|
|
2
|
+
// app/page.tsx
|
|
3
|
+
|
|
4
|
+
import { Navbar } from "@/components/layout/Navbar";
|
|
5
|
+
import { HeroSection } from "@/components/sections/HeroSection";
|
|
6
|
+
|
|
1
7
|
export default function Home() {
|
|
2
8
|
return (
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
|
|
9
|
+
<>
|
|
10
|
+
<Navbar />
|
|
11
|
+
<HeroSection />
|
|
12
|
+
</>
|
|
6
13
|
);
|
|
7
14
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
|
|
6
|
+
const NAV_LINKS = [
|
|
7
|
+
{ label: "Accommodations", href: "/accommodations" },
|
|
8
|
+
{ label: "Experiences", href: "/experiences" },
|
|
9
|
+
{ label: "Gallery", href: "/gallery" },
|
|
10
|
+
{ label: "About", href: "/about" },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export function Navbar() {
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<header
|
|
18
|
+
className="fixed top-0 left-0 right-0 z-50"
|
|
19
|
+
style={{ height: "var(--spacing-navbar)" }}
|
|
20
|
+
>
|
|
21
|
+
{/* Glass bar */}
|
|
22
|
+
<div
|
|
23
|
+
className="h-full flex items-center justify-between px-6 md:px-12"
|
|
24
|
+
style={{
|
|
25
|
+
background: "rgba(255,255,255,0.06)",
|
|
26
|
+
backdropFilter: "blur(12px)",
|
|
27
|
+
borderBottom: "1px solid rgba(255,255,255,0.08)",
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{/* Logo */}
|
|
31
|
+
<Link
|
|
32
|
+
href="/"
|
|
33
|
+
className="font-display text-white text-xl tracking-tight"
|
|
34
|
+
style={{ letterSpacing: "-0.03em" }}
|
|
35
|
+
>
|
|
36
|
+
MERIDIAN
|
|
37
|
+
</Link>
|
|
38
|
+
|
|
39
|
+
{/* Desktop nav */}
|
|
40
|
+
<nav className="hidden md:flex items-center gap-8">
|
|
41
|
+
{NAV_LINKS.map((l) => (
|
|
42
|
+
<Link
|
|
43
|
+
key={l.href}
|
|
44
|
+
href={l.href}
|
|
45
|
+
className="font-body text-xs tracking-widest uppercase text-white/70 hover:text-white transition-colors duration-200"
|
|
46
|
+
>
|
|
47
|
+
{l.label}
|
|
48
|
+
</Link>
|
|
49
|
+
))}
|
|
50
|
+
</nav>
|
|
51
|
+
|
|
52
|
+
{/* CTA */}
|
|
53
|
+
<Link
|
|
54
|
+
href="/accommodations"
|
|
55
|
+
className="hidden md:inline-flex btn btn-white btn-sm"
|
|
56
|
+
style={{ marginTop: 0 }}
|
|
57
|
+
>
|
|
58
|
+
Book a Stay
|
|
59
|
+
</Link>
|
|
60
|
+
|
|
61
|
+
{/* Mobile hamburger */}
|
|
62
|
+
<button
|
|
63
|
+
className="md:hidden flex flex-col gap-1.5 p-2"
|
|
64
|
+
onClick={() => setOpen((o) => !o)}
|
|
65
|
+
aria-label="Toggle menu"
|
|
66
|
+
>
|
|
67
|
+
<span
|
|
68
|
+
className="block w-6 h-px bg-white transition-all duration-300"
|
|
69
|
+
style={{ transform: open ? "translateY(4px) rotate(45deg)" : "none" }}
|
|
70
|
+
/>
|
|
71
|
+
<span
|
|
72
|
+
className="block w-6 h-px bg-white transition-all duration-300"
|
|
73
|
+
style={{ transform: open ? "translateY(-4px) rotate(-45deg)" : "none" }}
|
|
74
|
+
/>
|
|
75
|
+
</button>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{/* Mobile menu */}
|
|
79
|
+
{open && (
|
|
80
|
+
<div
|
|
81
|
+
className="md:hidden flex flex-col px-6 py-6 gap-5"
|
|
82
|
+
style={{ background: "rgba(20,8,12,0.97)", backdropFilter: "blur(12px)" }}
|
|
83
|
+
>
|
|
84
|
+
{NAV_LINKS.map((l) => (
|
|
85
|
+
<Link
|
|
86
|
+
key={l.href}
|
|
87
|
+
href={l.href}
|
|
88
|
+
onClick={() => setOpen(false)}
|
|
89
|
+
className="font-body text-sm tracking-widest uppercase text-white/80 hover:text-white transition-colors"
|
|
90
|
+
>
|
|
91
|
+
{l.label}
|
|
92
|
+
</Link>
|
|
93
|
+
))}
|
|
94
|
+
<Link
|
|
95
|
+
href="/accommodations"
|
|
96
|
+
className="btn btn-primary btn-sm w-fit"
|
|
97
|
+
style={{ marginTop: "0.5rem" }}
|
|
98
|
+
>
|
|
99
|
+
Book a Stay
|
|
100
|
+
</Link>
|
|
101
|
+
</div>
|
|
102
|
+
)}
|
|
103
|
+
</header>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// ── Hero Section ──────────────────────────────────────────────────────────────
|
|
2
|
+
// components/sections/HeroSection.tsx
|
|
3
|
+
|
|
4
|
+
import Image from "next/image";
|
|
5
|
+
import Link from "next/link";
|
|
6
|
+
|
|
7
|
+
export function HeroSection() {
|
|
8
|
+
return (
|
|
9
|
+
<section className="relative w-full h-screen overflow-hidden bg-black">
|
|
10
|
+
{/* Background image — swap src for your hero image or video */}
|
|
11
|
+
<Image
|
|
12
|
+
src="https://assets.lummi.ai/assets/QmVYR4iGjd71gxXKjJUFbD54ZuzEjyRYg4NUmyQnz7rQgU?auto=format&w=1500"
|
|
13
|
+
alt="Resort hero"
|
|
14
|
+
fill
|
|
15
|
+
priority
|
|
16
|
+
className="object-cover"
|
|
17
|
+
sizes="100vw"
|
|
18
|
+
/>
|
|
19
|
+
|
|
20
|
+
{/* Gradient overlay */}
|
|
21
|
+
<div
|
|
22
|
+
className="absolute inset-0"
|
|
23
|
+
style={{
|
|
24
|
+
background:
|
|
25
|
+
"linear-gradient(to bottom, rgba(6, 4, 10, 0.3) 0%, rgba(10,4,6,0.15) 40%, rgba(10,4,6,0.6) 100%)",
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
|
|
29
|
+
{/* Content */}
|
|
30
|
+
<div className="absolute inset-0 flex flex-col justify-end pb-20 px-6 md:px-12 lg:px-20">
|
|
31
|
+
<div className="max-w-2xl">
|
|
32
|
+
{/* Location tag */}
|
|
33
|
+
<p className="font-body text-white/60 text-xs tracking-[0.3em] uppercase mb-6">
|
|
34
|
+
Maldives, Indian Ocean
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
{/* Headline */}
|
|
38
|
+
<h1
|
|
39
|
+
className="font-display text-white mb-8"
|
|
40
|
+
style={{
|
|
41
|
+
fontSize: "clamp(2.8rem, 7vw, 5.5rem)",
|
|
42
|
+
fontWeight: 400,
|
|
43
|
+
lineHeight: 0.95,
|
|
44
|
+
letterSpacing: "-0.03em",
|
|
45
|
+
textTransform: "uppercase",
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
Where stillness
|
|
49
|
+
<br />
|
|
50
|
+
meets the sea.
|
|
51
|
+
</h1>
|
|
52
|
+
|
|
53
|
+
{/* Sub + CTA row */}
|
|
54
|
+
<div className="flex flex-col sm:flex-row sm:items-end gap-6">
|
|
55
|
+
<p className="font-body text-white/60 text-sm leading-relaxed max-w-sm">
|
|
56
|
+
Private villas, overwater bungalows, and curated experiences for
|
|
57
|
+
those who seek something beyond ordinary.
|
|
58
|
+
</p>
|
|
59
|
+
|
|
60
|
+
<Link
|
|
61
|
+
href="/accommodations"
|
|
62
|
+
className="btn btn-white shrink-0"
|
|
63
|
+
style={{ marginTop: 0 }}
|
|
64
|
+
>
|
|
65
|
+
Explore Rooms
|
|
66
|
+
</Link>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{/* Scroll indicator */}
|
|
72
|
+
<div className="absolute bottom-8 right-8 flex flex-col items-center gap-2">
|
|
73
|
+
<span
|
|
74
|
+
className="font-body text-white/40 text-[10px] tracking-[0.25em] uppercase"
|
|
75
|
+
style={{ writingMode: "vertical-rl" }}
|
|
76
|
+
>
|
|
77
|
+
Scroll
|
|
78
|
+
</span>
|
|
79
|
+
<div className="w-px h-12 bg-white/20 relative overflow-hidden">
|
|
80
|
+
<div
|
|
81
|
+
className="absolute top-0 left-0 w-full bg-white/60"
|
|
82
|
+
style={{
|
|
83
|
+
height: "40%",
|
|
84
|
+
animation: "scrollLine 1.8s ease-in-out infinite",
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<style>{`
|
|
91
|
+
@keyframes scrollLine {
|
|
92
|
+
0% { transform: translateY(-100%); }
|
|
93
|
+
100% { transform: translateY(350%); }
|
|
94
|
+
}
|
|
95
|
+
`}</style>
|
|
96
|
+
</section>
|
|
97
|
+
);
|
|
98
|
+
}
|