Compare commits

5 Commits

Author SHA1 Message Date
1bdc4ddc72 feat: improve responsive design for hero section
- Added responsive visibility classes to hide book tear image on mobile screens (md:block)
- Adjusted vertical spacing (-mt-14) to only apply on large screens, with mt-0 on mobile
- Increased horizontal padding in content section from px-6 to px-8 for better mobile spacing
- Updated Booktear component to be hidden on mobile and visible on md/lg breakpoints
2025-10-24 05:19:09 +02:00
a663cc038b feat: update mobile navigation styling for dark theme
- Changed mobile menu icon color from slate-700 to white for better contrast
- Updated mobile navigation panel background to use dark translucent style with backdrop blur
- Removed rounded corners and shadow effects from mobile menu panel
- Modified text color in mobile navigation to white to match dark theme
2025-10-24 05:14:01 +02:00
4a63edc0b0 feat: update navigation menu structure and layout
- Renamed navigation links to match new site structure (HOME → MENUS, EXPERIENCES → EVENTS, DAHABIYAS → CONTACT)
- Removed ITINERARY link from mobile navigation menu
- Improved mobile header layout with better spacing and alignment using justify-between
- Added spacer div in mobile view for balanced layout
- Simplified navigation container structure by removing nested flex containers
2025-10-24 05:12:46 +02:00
a6a0bbef0b feat: add typewriter animation effect to hero text
- Added typewriter-effect package for animated text rendering
- Implemented sequential typing animation for welcome message and signature
- Added client-side rendering check to prevent hydration issues
- Adjusted text opacity and timing delays for better readability
- Created invisible placeholder text to maintain layout during animation loading
2025-10-24 05:06:16 +02:00
c3bb18d495 feat: enhance visual styling with updated colors and layout
- Added base background color (#faeee0) to body element for consistent theme
- Added text color (slate-900) to body for improved readability
- Updated hero section spacing with -mt-14 margin and adjusted padding
- Changed tear image from booktear.png to booktear1.png for improved design
- Added new 'base' color variable to Tailwind config for theme consistency
2025-10-24 04:59:18 +02:00
9 changed files with 113 additions and 30 deletions

17
package-lock.json generated
View File

@@ -31,7 +31,8 @@
"react-use-measure": "^2.1.7", "react-use-measure": "^2.1.7",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"swiper": "^11.1.7", "swiper": "^11.1.7",
"tailwindcss": "^3.4.6" "tailwindcss": "^3.4.6",
"typewriter-effect": "^2.22.0"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.56.0", "eslint": "^8.56.0",
@@ -27468,6 +27469,20 @@
"node": ">=4.2.0" "node": ">=4.2.0"
} }
}, },
"node_modules/typewriter-effect": {
"version": "2.22.0",
"resolved": "https://registry.npmjs.org/typewriter-effect/-/typewriter-effect-2.22.0.tgz",
"integrity": "sha512-01HCRYY462wT8Fxps/epwGCioZd/GMXY0aLKhFKrfJ5Xhgf54/SiDx7Oq7PoES5kGqOEAdW8FS8HYVM2WSvfhQ==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1",
"raf": "^3.4.1"
},
"peerDependencies": {
"react": ">=17.0.0",
"react-dom": ">=17.0.0"
}
},
"node_modules/unbox-primitive": { "node_modules/unbox-primitive": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",

View File

@@ -33,7 +33,8 @@
"react-use-measure": "^2.1.7", "react-use-measure": "^2.1.7",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"swiper": "^11.1.7", "swiper": "^11.1.7",
"tailwindcss": "^3.4.6" "tailwindcss": "^3.4.6",
"typewriter-effect": "^2.22.0"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.56.0", "eslint": "^8.56.0",

BIN
public/images/booktear1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

View File

@@ -41,7 +41,7 @@ export default function RootLayout({ children }) {
jmhTypewriter.variable, jmhTypewriter.variable,
)} )}
> >
<body className="flex h-full flex-col pt-20"> <body className="flex h-full flex-col bg-base pt-20 text-slate-900">
{children} {children}
</body> </body>
</html> </html>

View File

@@ -26,7 +26,7 @@ function MobileNavIcon({ open }) {
return ( return (
<svg <svg
aria-hidden="true" aria-hidden="true"
className="h-3.5 w-3.5 overflow-visible stroke-slate-700" className="h-3.5 w-3.5 overflow-visible stroke-white"
fill="none" fill="none"
strokeWidth={2} strokeWidth={2}
strokeLinecap="round" strokeLinecap="round"
@@ -64,13 +64,12 @@ function MobileNavigation() {
/> />
<PopoverPanel <PopoverPanel
transition transition
className="absolute inset-x-0 top-full mt-4 flex origin-top flex-col rounded-lg bg-white p-4 text-lg tracking-tight text-slate-900 shadow-xl ring-1 ring-slate-900/5 data-[closed]:scale-95 data-[closed]:opacity-0 data-[enter]:duration-150 data-[leave]:duration-100 data-[enter]:ease-out data-[leave]:ease-in" className="absolute inset-x-0 top-full flex origin-top flex-col bg-black/10 p-4 text-lg tracking-tight text-white backdrop-blur-sm data-[closed]:scale-95 data-[closed]:opacity-0 data-[enter]:duration-150 data-[leave]:duration-100 data-[enter]:ease-out data-[leave]:ease-in"
> >
<MobileNavLink href="/">HOME</MobileNavLink> <MobileNavLink href="/">MENUS</MobileNavLink>
<MobileNavLink href="/story">STORY</MobileNavLink> <MobileNavLink href="/story">STORY</MobileNavLink>
<MobileNavLink href="/experiences">EXPERIENCES</MobileNavLink> <MobileNavLink href="/experiences">EVENTS</MobileNavLink>
<MobileNavLink href="/dahabiyas">DAHABIYAS</MobileNavLink> <MobileNavLink href="/dahabiyas">CONTACT</MobileNavLink>
<MobileNavLink href="/itinerary">ITINERARY</MobileNavLink>
</PopoverPanel> </PopoverPanel>
</Popover> </Popover>
) )
@@ -80,8 +79,9 @@ export function Header() {
return ( return (
<header className="fixed top-0 left-0 right-0 z-50 bg-black/10 backdrop-blur-sm py-3"> <header className="fixed top-0 left-0 right-0 z-50 bg-black/10 backdrop-blur-sm py-3">
<Container> <Container>
<nav className="relative z-50 flex justify-center"> <nav className="relative z-50 flex items-center justify-between md:justify-center">
<div className="flex items-center md:gap-x-12"> <div className="md:hidden" /> {/* Spacer for mobile */}
<div className="flex items-center gap-x-5 md:gap-x-8">
<div className="hidden md:flex md:gap-x-6"> <div className="hidden md:flex md:gap-x-6">
<NavLink href="/">MENUS</NavLink> <NavLink href="/">MENUS</NavLink>
<NavLink href="/story">STORY</NavLink> <NavLink href="/story">STORY</NavLink>
@@ -89,10 +89,8 @@ export function Header() {
<NavLink href="/dahabiyas">CONTACT</NavLink> <NavLink href="/dahabiyas">CONTACT</NavLink>
</div> </div>
</div> </div>
<div className="flex items-center gap-x-5 md:gap-x-8"> <div className="md:hidden">
<div className="-mr-1 md:hidden"> <MobileNavigation />
<MobileNavigation />
</div>
</div> </div>
</nav> </nav>
</Container> </Container>

View File

@@ -1,9 +1,19 @@
'use client'
import Image from 'next/image' import Image from 'next/image'
import { useState, useEffect } from 'react'
import Typewriter from 'typewriter-effect'
import { Button } from '@/components/Button' import { Button } from '@/components/Button'
import { Container } from '@/components/Container' import { Container } from '@/components/Container'
import BgNoise from '@/components/BgNoise' import BgNoise from '@/components/BgNoise'
export function Hero() { export function Hero() {
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
return ( return (
<> <>
<div className="relative -mt-20 min-h-screen"> <div className="relative -mt-20 min-h-screen">
@@ -24,10 +34,10 @@ export function Hero() {
</div> </div>
</Container> </Container>
</div> </div>
<div className="relative"> <div className="relative hidden md:block">
<Image <Image
unoptimized unoptimized
src="/images/booktear.png" src="/images/booktear1.png"
alt="Page divider" alt="Page divider"
width={1080} width={1080}
height={200} height={200}
@@ -36,19 +46,69 @@ export function Hero() {
</div> </div>
<div className="relative"> <div className="relative">
<div <div
className="bg-cover bg-center" className="bg-cover bg-center lg:-mt-14 mt-0"
style={{ backgroundImage: 'url(/images/paper.jpg)' }} style={{ backgroundImage: 'url(/images/paper.jpg)', opacity: '0.9' }}
> >
<div className="px-6 py-24 sm:py-32 lg:px-8"> <div className="px-8 py-24 lg:px-8">
<div className="mx-auto max-w-2xl text-left"> <div className="mx-auto max-w-2xl text-left">
<p className="font-script text-2xl text-love-red mb-2 font-typewriter">Mon cher,</p> <p className="font-script text-2xl text-love-red mb-2 font-typewriter relative">
<p className="font-typewriter text-xl max-w-2xl mx-auto leading-relaxed"> <span className="invisible">Mon cher,</span>
If you find yourself here, youve survived the noise.<br /> {isClient && (
Sit, let the glass sweat a little.<br /> <span className="absolute top-0 left-0">
The band will start soon, and perhaps someone will meet your eyes before the chorus ends.<br /> <Typewriter
If not, the night still owes you a dance. options={{
delay: 75,
}}
onInit={(typewriter) => {
typewriter.typeString('Mon cher,').start()
}}
/>
</span>
)}
</p>
<p className="font-typewriter text-xl max-w-2xl mx-auto leading-relaxed relative">
<span className="invisible" dangerouslySetInnerHTML={{ __html: 'If you find yourself here, youve survived the noise.<br />Sit, let the glass sweat a little.<br />The band will start soon, and perhaps someone will meet your eyes before the chorus ends.<br />If not, the night still owes you a dance.' }} />
{isClient && (
<span className="absolute top-0 left-0">
<Typewriter
options={{
delay: 50,
}}
onInit={(typewriter) => {
typewriter
.pauseFor(2000)
.typeString(
'If you find yourself here, youve survived the noise.<br />',
)
.pauseFor(500)
.typeString('Sit, let the glass sweat a little.<br />')
.pauseFor(500)
.typeString(
'The band will start soon, and perhaps someone will meet your eyes before the chorus ends.<br />',
)
.pauseFor(500)
.typeString('If not, the night still owes you a dance.')
.start()
}}
/>
</span>
)}
</p>
<p className="font-script text-xl text-love-red mt-6 font-typewriter relative">
<span className="invisible"> M.N.</span>
{isClient && (
<span className="absolute top-0 left-0">
<Typewriter
onInit={(typewriter) => {
typewriter
.pauseFor(17000)
.typeString('— M.N.')
.start()
}}
/>
</span>
)}
</p> </p>
<p className="font-script text-xl text-love-red mt-6 font-typewriter"> M.N.</p>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -2,7 +2,7 @@ import Image from 'next/image';
const Booktear = ({ className }) => { const Booktear = ({ className }) => {
return ( return (
<div className={`w-full bg-transparent ${className || ''}`}> <div className={`hidden md:block lg:block w-full bg-transparent ${className || ''}`}>
<Image <Image
unoptimized unoptimized
src="/images/booktear.png" src="/images/booktear.png"

View File

@@ -52,6 +52,7 @@ module.exports = {
200: '#E4E7EB', 200: '#E4E7EB',
}, },
'love-red': '#bc0a0f', 'love-red': '#bc0a0f',
base: '#faeee0',
creme: { creme: {
900: '#e3dfda', 900: '#e3dfda',
600: '#f6f1eb', 600: '#f6f1eb',

View File

@@ -11064,7 +11064,7 @@ react-dev-utils@^11.0.3:
strip-ansi "6.0.0" strip-ansi "6.0.0"
text-table "0.2.0" text-table "0.2.0"
react-dom@*, "react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^18, "react-dom@^18.0.0 || ^19.0.0", react-dom@^18.2.0, react-dom@>=16, react-dom@>=16.13, react-dom@>=16.6.0, react-dom@>=16.8.0: react-dom@*, "react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^18, "react-dom@^18.0.0 || ^19.0.0", react-dom@^18.2.0, react-dom@>=16, react-dom@>=16.13, react-dom@>=16.6.0, react-dom@>=16.8.0, react-dom@>=17.0.0:
version "18.3.1" version "18.3.1"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
@@ -11208,7 +11208,7 @@ react-use-measure@^2.1.7:
resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz" resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz"
integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg== integrity sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==
react@*, "react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", react@^18, "react@^18.0.0 || ^19.0.0", react@^18.2.0, react@^18.3.1, "react@>= 16", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16, react@>=16.13, react@>=16.6.0, react@>=16.8.0: react@*, "react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0", "react@^17.0.0 || ^18.0.0 || ^19.0.0", react@^18, "react@^18.0.0 || ^19.0.0", react@^18.2.0, react@^18.3.1, "react@>= 16", "react@>= 16.8.0 || 17.x.x || ^18.0.0-0", react@>=16, react@>=16.13, react@>=16.6.0, react@>=16.8.0, react@>=17.0.0:
version "18.3.1" version "18.3.1"
resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
@@ -13182,6 +13182,14 @@ typedarray@^0.0.6:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
typewriter-effect@^2.22.0:
version "2.22.0"
resolved "https://registry.npmjs.org/typewriter-effect/-/typewriter-effect-2.22.0.tgz"
integrity sha512-01HCRYY462wT8Fxps/epwGCioZd/GMXY0aLKhFKrfJ5Xhgf54/SiDx7Oq7PoES5kGqOEAdW8FS8HYVM2WSvfhQ==
dependencies:
prop-types "^15.8.1"
raf "^3.4.1"
unbox-primitive@^1.0.2: unbox-primitive@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"