blog: updated blog
This commit is contained in:
15 files changed
+1013
-647
No files matched your search
@@ -0,0 +1,424 @@
|
||||
Redesign the existing company portfolio website using a premium editorial / modern digital-agency design language.
|
||||
|
||||
IMPORTANT:
|
||||
|
||||
- The existing project already contains the company's content, pages, functionality, assets, routes, components, and business information.
|
||||
- Do NOT rebuild the project from scratch.
|
||||
- Do NOT remove existing functionality.
|
||||
- First inspect and understand the entire existing codebase, including all pages, components, content, images, assets, routes, responsive behavior, and existing design system.
|
||||
- Preserve the company's actual content and business information unless something clearly needs restructuring for the new visual hierarchy.
|
||||
- The primary goal is a COMPLETE VISUAL AND UX REDESIGN.
|
||||
- Do not make it look like a generic SaaS template or an AI-generated website.
|
||||
|
||||
## DESIGN DIRECTION
|
||||
|
||||
Use a sophisticated:
|
||||
|
||||
"Premium Editorial + Swiss Minimalism + Contemporary Digital Agency"
|
||||
|
||||
aesthetic.
|
||||
|
||||
The website should feel like a high-end international creative agency / architecture studio / luxury brand website rather than a conventional corporate website.
|
||||
|
||||
The visual language should combine:
|
||||
|
||||
- Swiss-inspired typography
|
||||
- Editorial magazine layouts
|
||||
- Premium corporate branding
|
||||
- Large-scale typography
|
||||
- Asymmetric compositions
|
||||
- Strong grid systems
|
||||
- Generous whitespace
|
||||
- Large immersive photography
|
||||
- Minimal UI
|
||||
- Sophisticated motion
|
||||
- Strong visual hierarchy
|
||||
- Intentional negative space
|
||||
- Subtle organic shapes
|
||||
- Restrained use of color
|
||||
- High-quality transitions and micro-interactions
|
||||
|
||||
The final result should feel expensive, intentional, confident, and highly designed.
|
||||
|
||||
## TYPOGRAPHY
|
||||
|
||||
Typography is one of the most important parts of the redesign.
|
||||
|
||||
Use typography as a major visual element rather than simply displaying text.
|
||||
|
||||
Use:
|
||||
|
||||
- Extremely large display headings
|
||||
- Strong contrast between display and body typography
|
||||
- Large section titles
|
||||
- Tight but carefully controlled heading line-height
|
||||
- Clear typographic hierarchy
|
||||
- Editorial-style text blocks
|
||||
- Occasional oversized numbers/statistics
|
||||
- Small uppercase labels with subtle letter spacing
|
||||
- Short, confident headlines
|
||||
|
||||
Avoid excessive font weights and unnecessary decorative typography.
|
||||
|
||||
The typography should feel modern, sophisticated, and editorial.
|
||||
|
||||
## LAYOUT
|
||||
|
||||
Do NOT make every section centered.
|
||||
|
||||
Use a strong responsive grid with intentional asymmetry.
|
||||
|
||||
Use compositions such as:
|
||||
|
||||
- Text aligned to one side with large imagery on the other
|
||||
- Full-width images
|
||||
- Oversized headings extending across multiple grid columns
|
||||
- Offset content blocks
|
||||
- Uneven image/text ratios
|
||||
- Large whitespace areas
|
||||
- Overlapping elements when appropriate
|
||||
- Editorial multi-column layouts
|
||||
- Large visual pauses between sections
|
||||
|
||||
The page should feel composed rather than assembled from UI components.
|
||||
|
||||
Do not make every section look like:
|
||||
|
||||
heading → paragraph → three cards.
|
||||
|
||||
## HERO
|
||||
|
||||
Create a visually dominant hero section.
|
||||
|
||||
The hero should immediately communicate the company's identity.
|
||||
|
||||
Use:
|
||||
|
||||
- Very large typography
|
||||
- Strong composition
|
||||
- High-quality company imagery
|
||||
- Minimal supporting text
|
||||
- Minimal CTA treatment
|
||||
- Plenty of negative space
|
||||
- Subtle entrance animation
|
||||
|
||||
Avoid the typical SaaS hero pattern.
|
||||
|
||||
Do not use a huge gradient background with floating cards.
|
||||
|
||||
The hero should feel like the opening spread of a premium magazine.
|
||||
|
||||
## NAVIGATION
|
||||
|
||||
Create a minimal, sophisticated navigation.
|
||||
|
||||
Keep the navigation visually quiet.
|
||||
|
||||
Use:
|
||||
|
||||
- Simple logo
|
||||
- Minimal navigation links
|
||||
- Strong spacing
|
||||
- Subtle hover interactions
|
||||
- Optional menu interaction on smaller screens
|
||||
- Sticky/floating behavior only if it improves the experience
|
||||
|
||||
Do not overcrowd the navbar.
|
||||
|
||||
Navigation should never compete with the content.
|
||||
|
||||
## IMAGERY
|
||||
|
||||
Treat images as part of the design rather than simple content containers.
|
||||
|
||||
Use:
|
||||
|
||||
- Large editorial photographs
|
||||
- Full-width imagery
|
||||
- Carefully cropped images
|
||||
- Different aspect ratios
|
||||
- Asymmetric image compositions
|
||||
- Subtle border radius where appropriate
|
||||
- Image reveal animations
|
||||
- Hover transformations that are subtle and sophisticated
|
||||
|
||||
Avoid putting every image inside a standard rounded rectangular card.
|
||||
|
||||
If the existing project already has images, reuse them intelligently.
|
||||
|
||||
Do not replace real company imagery with random stock imagery unless absolutely necessary.
|
||||
|
||||
## SECTIONS
|
||||
|
||||
Reorganize the visual presentation of existing content into a strong editorial narrative.
|
||||
|
||||
Possible visual rhythm:
|
||||
|
||||
1. Minimal navigation
|
||||
2. Massive hero statement
|
||||
3. Introductory company statement
|
||||
4. Large visual / company image
|
||||
5. Company capabilities or services
|
||||
6. Featured projects
|
||||
7. Individual project showcases
|
||||
8. Company statistics / achievements
|
||||
9. About/company story
|
||||
10. Process or expertise
|
||||
11. Clients / partners
|
||||
12. Testimonials if they already exist
|
||||
13. Strong CTA
|
||||
14. Minimal footer
|
||||
|
||||
Do not blindly follow this order.
|
||||
|
||||
Analyze the existing company's content and determine the most natural narrative.
|
||||
|
||||
## PROJECT / PORTFOLIO SECTION
|
||||
|
||||
Projects should feel like editorial case studies.
|
||||
|
||||
Avoid generic grids of identical cards.
|
||||
|
||||
Instead use:
|
||||
|
||||
- Large featured project
|
||||
- Different image sizes
|
||||
- Asymmetric layouts
|
||||
- Project number/category labels
|
||||
- Large project titles
|
||||
- Metadata presented subtly
|
||||
- Image hover interactions
|
||||
- Alternating compositions
|
||||
|
||||
Example visual rhythm:
|
||||
|
||||
Large project
|
||||
↓
|
||||
Two smaller projects
|
||||
↓
|
||||
Large offset project
|
||||
↓
|
||||
Full-width project
|
||||
↓
|
||||
Next major section
|
||||
|
||||
The portfolio should feel curated rather than like a database.
|
||||
|
||||
## SERVICES / CAPABILITIES
|
||||
|
||||
Do not create generic SaaS feature cards.
|
||||
|
||||
Instead present services using editorial typography.
|
||||
|
||||
For example:
|
||||
|
||||
01 — SERVICE NAME
|
||||
Short description
|
||||
|
||||
02 — SERVICE NAME
|
||||
Short description
|
||||
|
||||
03 — SERVICE NAME
|
||||
Short description
|
||||
|
||||
Allow typography, spacing, dividers, and interaction to create the hierarchy.
|
||||
|
||||
If cards are appropriate for the existing content, make them editorial rather than conventional UI cards.
|
||||
|
||||
## MOTION
|
||||
|
||||
Use sophisticated motion throughout the website.
|
||||
|
||||
Animations should feel intentional and restrained.
|
||||
|
||||
Use:
|
||||
|
||||
- Text reveal animations
|
||||
- Image reveal animations
|
||||
- Fade/slide transitions
|
||||
- Subtle scale transformations
|
||||
- Hover interactions
|
||||
- Staggered content reveals
|
||||
- Smooth section transitions
|
||||
- Marquee/scrolling elements where appropriate
|
||||
- Subtle parallax where it genuinely improves the composition
|
||||
|
||||
Motion should support the design rather than become a spectacle.
|
||||
|
||||
Avoid:
|
||||
|
||||
- Excessive bouncing
|
||||
- Random animations
|
||||
- Constant floating elements
|
||||
- Overly aggressive parallax
|
||||
- Long loading animations
|
||||
- Animations that hurt usability
|
||||
|
||||
Respect prefers-reduced-motion.
|
||||
|
||||
## MARQUEE / SCROLLING ELEMENTS
|
||||
|
||||
Where appropriate, introduce editorial scrolling elements such as:
|
||||
|
||||
COMPANY • SERVICES • PROJECTS • EXPERTISE • COMPANY • SERVICES • PROJECTS
|
||||
|
||||
Use them sparingly.
|
||||
|
||||
They should feel like part of the visual identity rather than a gimmick.
|
||||
|
||||
## COLORS
|
||||
|
||||
Use the company's existing brand colors as the foundation.
|
||||
|
||||
Do not blindly introduce purple/blue gradients.
|
||||
|
||||
Prefer:
|
||||
|
||||
- Strong neutral base
|
||||
- Black/near-black
|
||||
- White/off-white
|
||||
- Existing brand accent
|
||||
- Very limited secondary colors
|
||||
|
||||
Color should support typography and imagery.
|
||||
|
||||
If the existing brand palette is poor, refine it rather than completely replacing the brand identity.
|
||||
|
||||
## BORDERS / SHADOWS / CARDS
|
||||
|
||||
Use visual restraint.
|
||||
|
||||
Prefer:
|
||||
|
||||
- Thin borders
|
||||
- Dividers
|
||||
- Whitespace
|
||||
- Typography
|
||||
- Image composition
|
||||
|
||||
Avoid excessive:
|
||||
|
||||
- Box shadows
|
||||
- Glassmorphism
|
||||
- Gradient borders
|
||||
- Floating cards
|
||||
- Pills
|
||||
- Huge border radiuses
|
||||
|
||||
Not every element needs a container.
|
||||
|
||||
## FOOTER
|
||||
|
||||
Create a strong editorial footer.
|
||||
|
||||
The footer should feel like the final page of a magazine rather than a standard corporate footer.
|
||||
|
||||
Use:
|
||||
|
||||
- Large company statement
|
||||
- Contact information
|
||||
- Important navigation
|
||||
- Social links if already present
|
||||
- Location information if relevant
|
||||
- Large typography
|
||||
- Minimal legal links
|
||||
- Strong whitespace
|
||||
|
||||
## RESPONSIVE DESIGN
|
||||
|
||||
The design must be genuinely responsive.
|
||||
|
||||
Do not simply shrink the desktop version.
|
||||
|
||||
Create intentional layouts for:
|
||||
|
||||
- Large desktop
|
||||
- Laptop
|
||||
- Tablet
|
||||
- Mobile
|
||||
|
||||
On mobile:
|
||||
|
||||
- Preserve the typography hierarchy
|
||||
- Maintain the editorial feel
|
||||
- Recompose asymmetric layouts
|
||||
- Carefully control oversized typography
|
||||
- Prevent horizontal overflow
|
||||
- Maintain image quality
|
||||
- Keep navigation simple
|
||||
- Preserve whitespace without wasting viewport space
|
||||
|
||||
## UX
|
||||
|
||||
Despite the highly visual design, usability must remain excellent.
|
||||
|
||||
Ensure:
|
||||
|
||||
- Clear navigation
|
||||
- Accessible contrast
|
||||
- Keyboard accessibility
|
||||
- Proper semantic HTML
|
||||
- Visible focus states
|
||||
- Accessible buttons and links
|
||||
- Proper heading hierarchy
|
||||
- Fast loading
|
||||
- Optimized images
|
||||
- No unnecessary JavaScript
|
||||
- No unnecessary dependencies
|
||||
|
||||
The website should look artistic without sacrificing usability.
|
||||
|
||||
## IMPORTANT ANTI-PATTERNS
|
||||
|
||||
Do NOT produce:
|
||||
|
||||
- Generic SaaS design
|
||||
- Generic corporate template
|
||||
- AI-looking website
|
||||
- Purple gradient hero
|
||||
- Glassmorphism
|
||||
- Excessive rounded cards
|
||||
- Dashboard-style layouts
|
||||
- Repeated 3-column cards
|
||||
- Excessive shadows
|
||||
- Excessive pills
|
||||
- Giant CTA buttons everywhere
|
||||
- Centered content in every section
|
||||
- Same-sized cards everywhere
|
||||
- Random decorative blobs
|
||||
- Unnecessary icons
|
||||
- Excessive animations
|
||||
- Stock-template appearance
|
||||
|
||||
## IMPLEMENTATION
|
||||
|
||||
Before changing code:
|
||||
|
||||
1. Inspect the entire existing project.
|
||||
2. Identify the current architecture.
|
||||
3. Identify reusable components.
|
||||
4. Identify existing routes/pages.
|
||||
5. Identify existing assets and images.
|
||||
6. Identify the company's actual brand colors.
|
||||
7. Identify existing functionality that must remain.
|
||||
8. Identify opportunities to improve the information hierarchy.
|
||||
9. Create a coherent design system based on the editorial direction.
|
||||
10. Then implement the redesign systematically.
|
||||
|
||||
Do not rewrite working functionality unnecessarily.
|
||||
|
||||
Reuse existing components when technically appropriate, but redesign their visual presentation where necessary.
|
||||
|
||||
Keep the code clean, maintainable, responsive, and production-ready.
|
||||
|
||||
The final website should feel like a website designed by a high-end digital agency, not a collection of UI components.
|
||||
|
||||
MOST IMPORTANT:
|
||||
|
||||
The goal is not to copy another website.
|
||||
|
||||
The goal is to reproduce the same DESIGN PHILOSOPHY:
|
||||
|
||||
large typography + editorial composition + asymmetric grid + premium imagery + whitespace + restrained UI + sophisticated motion + strong visual identity.
|
||||
|
||||
Make the existing company feel like a premium, established, internationally credible brand through visual design alone.
|
||||
@@ -59,10 +59,10 @@ export function ClientsMarquee({
|
||||
<img
|
||||
src={client.logo}
|
||||
alt={client.name}
|
||||
className="h-16 w-32 object-contain filter grayscale transition-all duration-300 group-hover:grayscale-0 group-hover:scale-110 opacity-70 group-hover:opacity-100"
|
||||
className="h-16 w-32 object-contain transition-all duration-300 hover:scale-110 opacity-90 hover:opacity-100"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-xl font-bold tracking-widest text-muted-foreground transition-colors group-hover:text-brand">
|
||||
<span className="text-xl font-bold tracking-widest text-muted-foreground transition-colors group-hover:text-foreground">
|
||||
{client.name}
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -20,74 +20,65 @@ export function Footer() {
|
||||
|
||||
|
||||
return (
|
||||
<footer className="relative z-10 bg-[#0A0A0A] text-white pt-24 overflow-hidden border-t border-white/5">
|
||||
<footer className="relative z-10 bg-ink text-background pt-32 overflow-hidden">
|
||||
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10">
|
||||
<div className="flex flex-col lg:flex-row gap-16 lg:gap-24 mb-20 lg:mb-32">
|
||||
<div className="flex flex-col lg:flex-row gap-16 lg:gap-24 mb-32">
|
||||
{/* Logo and Copyright */}
|
||||
<div className="flex flex-col lg:w-[35%] shrink-0">
|
||||
<div className="flex items-center gap-3">
|
||||
{org?.logo ? (
|
||||
<img src={org.logo} alt={org?.name || "Udhamsil Nepal"} className="h-9 w-auto object-contain bg-white rounded p-1" />
|
||||
) : (
|
||||
<span className="grid h-9 w-9 place-items-center bg-white font-display text-sm font-bold text-black rounded">
|
||||
{org?.name ? org.name.charAt(0) : "U"}
|
||||
</span>
|
||||
)}
|
||||
<span className="font-display text-lg font-bold">{org?.name || "Udhamsil Nepal"}</span>
|
||||
<span className="font-display text-2xl font-bold tracking-tight">{org?.name || "UDHAMSIL"}</span>
|
||||
</div>
|
||||
<p className="mt-5 text-[13px] text-white/40">
|
||||
© copyright {org?.name || "Udhamsil Nepal"} {new Date().getFullYear()}.<br />All rights reserved.
|
||||
<p className="mt-8 text-xs font-medium uppercase tracking-widest text-background/40">
|
||||
© {new Date().getFullYear()} {org?.name || "Udhamsil Nepal"}.<br />All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Links Columns */}
|
||||
<div className="flex-1 grid grid-cols-2 md:grid-cols-4 gap-10">
|
||||
<div className="flex-1 grid grid-cols-2 md:grid-cols-4 gap-12">
|
||||
{/* Pages */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h4 className="text-sm font-semibold text-white">PAGES</h4>
|
||||
<nav className="flex flex-col gap-4 text-[13px] text-white/50">
|
||||
<Link to="/about" className="hover:text-white transition-colors">About Us</Link>
|
||||
<Link to="/products" className="hover:text-white transition-colors">Products</Link>
|
||||
<Link to="/projects-events" className="hover:text-white transition-colors">Projects & Events</Link>
|
||||
<Link to="/team" className="hover:text-white transition-colors">Team</Link>
|
||||
<Link to="/career" className="hover:text-white transition-colors">Career</Link>
|
||||
<div className="flex flex-col gap-8">
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-background/30">Index</h4>
|
||||
<nav className="flex flex-col gap-4 text-sm font-medium text-background/70">
|
||||
<Link to="/about" className="hover:text-background transition-colors">About</Link>
|
||||
<Link to="/products" className="hover:text-background transition-colors">Products</Link>
|
||||
<Link to="/projects-events" className="hover:text-background transition-colors">Projects</Link>
|
||||
<Link to="/team" className="hover:text-background transition-colors">Team</Link>
|
||||
<Link to="/career" className="hover:text-background transition-colors">Careers</Link>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Socials */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h4 className="text-sm font-semibold text-white">SOCIALS</h4>
|
||||
<nav className="flex flex-col gap-4 text-[13px] text-white/50">
|
||||
{org?.facebook && <a href={org.facebook} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">Facebook</a>}
|
||||
{org?.instagram && <a href={org.instagram} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">Instagram</a>}
|
||||
{org?.linkedin && <a href={org.linkedin} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">LinkedIn</a>}
|
||||
{org?.youtube && <a href={org.youtube} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">YouTube</a>}
|
||||
{org?.tiktok && <a href={org.tiktok} target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">TikTok</a>}
|
||||
<div className="flex flex-col gap-8">
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-background/30">Network</h4>
|
||||
<nav className="flex flex-col gap-4 text-sm font-medium text-background/70">
|
||||
{org?.facebook && <a href={org.facebook} target="_blank" rel="noopener noreferrer" className="hover:text-background transition-colors">Facebook</a>}
|
||||
{org?.instagram && <a href={org.instagram} target="_blank" rel="noopener noreferrer" className="hover:text-background transition-colors">Instagram</a>}
|
||||
{org?.linkedin && <a href={org.linkedin} target="_blank" rel="noopener noreferrer" className="hover:text-background transition-colors">LinkedIn</a>}
|
||||
{org?.youtube && <a href={org.youtube} target="_blank" rel="noopener noreferrer" className="hover:text-background transition-colors">YouTube</a>}
|
||||
{org?.tiktok && <a href={org.tiktok} target="_blank" rel="noopener noreferrer" className="hover:text-background transition-colors">TikTok</a>}
|
||||
{(!org || (!org.facebook && !org.instagram && !org.linkedin && !org.youtube && !org.tiktok)) && (
|
||||
<>
|
||||
<span className="opacity-50 hover:text-white cursor-pointer transition-colors">Facebook</span>
|
||||
<span className="opacity-50 hover:text-white cursor-pointer transition-colors">Instagram</span>
|
||||
<span className="opacity-50 hover:text-white cursor-pointer transition-colors">LinkedIn</span>
|
||||
<span className="opacity-50 hover:text-background cursor-pointer transition-colors">Instagram</span>
|
||||
<span className="opacity-50 hover:text-background cursor-pointer transition-colors">LinkedIn</span>
|
||||
</>
|
||||
)}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Legal */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h4 className="text-sm font-semibold text-white">LEGAL</h4>
|
||||
<nav className="flex flex-col gap-4 text-[13px] text-white/50">
|
||||
<Link to="#" className="hover:text-white transition-colors">Privacy Policy</Link>
|
||||
<Link to="#" className="hover:text-white transition-colors">Terms of Service</Link>
|
||||
<Link to="#" className="hover:text-white transition-colors">Cookie Policy</Link>
|
||||
<div className="flex flex-col gap-8">
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-background/30">Legal</h4>
|
||||
<nav className="flex flex-col gap-4 text-sm font-medium text-background/70">
|
||||
<Link to="#" className="hover:text-background transition-colors">Privacy</Link>
|
||||
<Link to="#" className="hover:text-background transition-colors">Terms</Link>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Contact */}
|
||||
<div className="flex flex-col gap-6">
|
||||
<h4 className="text-sm font-semibold text-white">CONTACT</h4>
|
||||
<nav className="flex flex-col gap-4 text-[13px] text-white/50">
|
||||
<Link to="/contact" className="hover:text-white transition-colors">Contact Us</Link>
|
||||
<div className="flex flex-col gap-8">
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-background/30">Contact</h4>
|
||||
<nav className="flex flex-col gap-4 text-sm font-medium text-background/70">
|
||||
<Link to="/contact" className="hover:text-background transition-colors">Get in touch</Link>
|
||||
<span title={org?.primary_email || "info@udhamsilnepal.com"}>{org?.primary_email || "info@udhamsilnepal.com"}</span>
|
||||
<span>{org?.phone_number || "+977-1234567890"}</span>
|
||||
</nav>
|
||||
@@ -99,10 +90,10 @@ export function Footer() {
|
||||
{/* Massive Bottom Text */}
|
||||
<div className="w-full flex justify-center overflow-hidden pointer-events-none select-none px-4">
|
||||
<h1
|
||||
className="font-black tracking-tighter text-white/[0.03] uppercase whitespace-nowrap"
|
||||
style={{ fontSize: "clamp(3rem, 11vw, 15rem)", lineHeight: 0.8, transform: "translateY(10%)" }}
|
||||
className="font-display font-black tracking-tighter text-background/5 uppercase whitespace-nowrap"
|
||||
style={{ fontSize: "clamp(3rem, 9.5vw, 15rem)", lineHeight: 0.75, transform: "translateY(15%)" }}
|
||||
>
|
||||
{org?.name ? org.name.replace('Global Trade Company', '').trim() : "UDHAMSIL NEPAL"}
|
||||
{org?.name ? org.name.replace('Global Trade Company', '').trim() : "UDHAMSIL"}
|
||||
</h1>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -26,30 +26,24 @@ export function Header() {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<header className="fixed top-0 inset-x-0 w-full z-50 border-b border-border bg-background/95 backdrop-blur-md transition-all duration-300">
|
||||
<header className="fixed top-0 inset-x-0 w-full z-50 bg-background/90 backdrop-blur-md transition-all duration-300">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6">
|
||||
<nav className="flex h-20 items-center justify-between gap-4">
|
||||
<Link to="/" className="flex items-center gap-3">
|
||||
<span className="grid h-10 w-10 place-items-center bg-brand font-display font-bold text-primary-foreground">
|
||||
U
|
||||
</span>
|
||||
<nav className="flex h-24 items-center justify-between gap-4">
|
||||
<Link to="/" className="flex items-center gap-4">
|
||||
<span className="leading-tight">
|
||||
<span className="block font-display text-[14px]">UDHAMSIL NEPAL</span>
|
||||
<span className="block text-[10px] uppercase text-muted-foreground">
|
||||
Global Trade Co.
|
||||
</span>
|
||||
<span className="block font-display text-lg tracking-wide">UDHAMSIL</span>
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<div className="hidden h-full items-center gap-7 text-sm font-semibold text-muted-foreground lg:flex">
|
||||
<div className="hidden h-full items-center gap-8 text-xs font-medium uppercase tracking-widest text-muted-foreground lg:flex">
|
||||
{links.map((l) => (
|
||||
<NavLink
|
||||
key={l.to}
|
||||
to={l.to}
|
||||
end={l.to === "/"}
|
||||
className={({ isActive }) =>
|
||||
`flex h-full items-center border-b-2 transition-colors hover:text-brand ${
|
||||
isActive ? "border-brand text-ink" : "border-transparent"
|
||||
`flex h-full items-center transition-colors hover:text-foreground ${
|
||||
isActive ? "text-foreground font-bold" : ""
|
||||
}`
|
||||
}
|
||||
>
|
||||
@@ -58,12 +52,12 @@ export function Header() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link
|
||||
to="/contact"
|
||||
className="hidden rounded-full bg-brand px-6 py-2.5 text-sm font-bold text-primary-foreground shadow-sm transition-all hover:scale-105 hover:bg-brand/90 sm:inline-block"
|
||||
className="hidden text-xs font-bold uppercase tracking-widest text-foreground transition-opacity hover:opacity-70 sm:inline-block"
|
||||
>
|
||||
Get a Quote
|
||||
Contact
|
||||
</Link>
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger asChild>
|
||||
|
||||
@@ -18,92 +18,127 @@ interface Organization {
|
||||
|
||||
export function OrbitalVisualization({ nodes }: { nodes: NodeData[] }) {
|
||||
const { data: org } = useApi<Organization>("org/organization");
|
||||
|
||||
|
||||
const RADIUS = {
|
||||
mobile: 140,
|
||||
desktop: 220,
|
||||
};
|
||||
// On desktop, radius is 430, box is 940, icon is 80
|
||||
// On mobile, radius is 140, box is 320, icon is 50
|
||||
const RADIUS = { desktop: 430, mobile: 140 };
|
||||
const BOX = { desktop: 940, mobile: 320 };
|
||||
const ICON = { desktop: 80, mobile: 50 };
|
||||
|
||||
return (
|
||||
<div className="relative mx-auto flex h-[500px] w-full max-w-3xl items-center justify-center overflow-hidden lg:h-[600px]">
|
||||
{/* Background Orbit Rings */}
|
||||
<div className="absolute h-[280px] w-[280px] rounded-full border border-dashed border-border/40 lg:h-[440px] lg:w-[440px]" />
|
||||
<div className="absolute h-[180px] w-[180px] rounded-full border border-border/20 lg:h-[260px] lg:w-[260px]" />
|
||||
|
||||
{/* Central Node */}
|
||||
<div className="relative z-10 flex h-24 w-24 flex-col items-center justify-center rounded-full border-2 border-brand/30 bg-background shadow-[0_0_40px_rgba(var(--brand-rgb),0.15)] lg:h-32 lg:w-32">
|
||||
<div className="absolute inset-0 rounded-full animate-ping bg-brand/10 opacity-75" style={{ animationDuration: '3s' }} />
|
||||
{org?.logo ? (
|
||||
<img src={org.logo} alt={org?.name || "Organization"} className="h-12 w-12 lg:h-16 lg:w-16 object-contain" />
|
||||
) : (
|
||||
<span className="font-display text-3xl font-black text-foreground">{org?.name ? org.name.charAt(0) : "UN"}</span>
|
||||
)}
|
||||
<div className="relative mx-auto flex w-full flex-col items-center justify-center overflow-hidden">
|
||||
|
||||
{/* Desktop Orbit */}
|
||||
<div className="relative z-0 hidden w-full max-w-[1000px] flex-col items-center justify-center overflow-clip h-[505px] md:flex">
|
||||
<div className="absolute left-1/2 top-0 -translate-x-1/2" style={{ width: BOX.desktop, height: BOX.desktop }}>
|
||||
{/* Dashed track */}
|
||||
<div
|
||||
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border border-dashed border-muted-foreground/30"
|
||||
style={{ width: RADIUS.desktop * 2, height: RADIUS.desktop * 2 }}
|
||||
/>
|
||||
<motion.div
|
||||
className="h-full w-full"
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 70, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
{nodes.map((node, i) => {
|
||||
const rad = ((i * 360) / nodes.length - 90) * (Math.PI / 180);
|
||||
const x = BOX.desktop / 2 + RADIUS.desktop * Math.sin(rad) - ICON.desktop / 2;
|
||||
const y = BOX.desktop / 2 - RADIUS.desktop * Math.cos(rad) - ICON.desktop / 2;
|
||||
return (
|
||||
<motion.div
|
||||
key={node.id}
|
||||
className="absolute flex items-center justify-center overflow-clip rounded-full bg-background shadow-[0_8px_20px_-8px_rgba(0,0,0,0.15)] ring-1 ring-border p-3"
|
||||
style={{ left: x, top: y, width: ICON.desktop, height: ICON.desktop }}
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: -360 }}
|
||||
transition={{ duration: 70, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
<NodeCard node={node} />
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Central Logo */}
|
||||
<div className="relative mt-[110px] flex max-w-[520px] flex-col items-center gap-[30px]">
|
||||
<span className="relative flex size-[130px] items-center justify-center rounded-full bg-background shadow-[0_12px_30px_rgba(0,0,0,0.1)]">
|
||||
<span aria-hidden className="absolute -inset-6 rounded-full ring-1 ring-border/50" />
|
||||
<span aria-hidden className="absolute -inset-12 rounded-full ring-1 ring-border/30" />
|
||||
{org?.logo ? (
|
||||
<img src={org.logo} alt={org?.name || "Organization"} className="size-[55%] object-contain" />
|
||||
) : (
|
||||
<span className="font-display text-4xl font-black text-foreground">{org?.name ? org.name.charAt(0) : "UN"}</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Orbiting Nodes */}
|
||||
<motion.div
|
||||
className="absolute left-1/2 top-1/2 z-20 h-0 w-0"
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 60, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
{nodes.map((node, i) => {
|
||||
const angle = (i / nodes.length) * 360;
|
||||
// Use standard trigonometry for positioning.
|
||||
// 0 degrees is right (positive X).
|
||||
const rad = (angle * Math.PI) / 180;
|
||||
{/* Mobile Orbit */}
|
||||
<div className="relative z-0 flex w-full flex-col items-center gap-[30px] md:hidden pt-8 pb-16">
|
||||
<div className="relative aspect-square w-full max-w-[340px]">
|
||||
<div className="absolute inset-0">
|
||||
{/* Dashed track */}
|
||||
<div
|
||||
className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border border-dashed border-muted-foreground/30"
|
||||
style={{ width: "80%", height: "80%" }}
|
||||
/>
|
||||
<motion.div
|
||||
className="h-full w-full"
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: 360 }}
|
||||
transition={{ duration: 70, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
{nodes.map((node, i) => {
|
||||
const rad = ((i * 360) / nodes.length - 90) * (Math.PI / 180);
|
||||
const r = 40; // 40%
|
||||
const x = 50 + r * Math.sin(rad);
|
||||
const y = 50 - r * Math.cos(rad);
|
||||
return (
|
||||
<motion.div
|
||||
key={node.id}
|
||||
className="absolute flex items-center justify-center overflow-clip rounded-full bg-background shadow-[0_8px_20px_-8px_rgba(0,0,0,0.15)] ring-1 ring-border p-2 -translate-x-1/2 -translate-y-1/2"
|
||||
style={{ left: `${x}%`, top: `${y}%`, width: ICON.mobile, height: ICON.mobile }}
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: -360 }}
|
||||
transition={{ duration: 70, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
<NodeCard node={node} />
|
||||
</motion.div>
|
||||
);
|
||||
})}
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
return (
|
||||
<React.Fragment key={node.id}>
|
||||
{/* Desktop position */}
|
||||
<motion.div
|
||||
className="absolute hidden -translate-x-1/2 -translate-y-1/2 md:block"
|
||||
style={{
|
||||
x: RADIUS.desktop * Math.cos(rad),
|
||||
y: RADIUS.desktop * Math.sin(rad),
|
||||
}}
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: -360 }}
|
||||
transition={{ duration: 60, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
<NodeCard node={node} />
|
||||
</motion.div>
|
||||
|
||||
{/* Mobile position */}
|
||||
<motion.div
|
||||
className="absolute -translate-x-1/2 -translate-y-1/2 md:hidden"
|
||||
style={{
|
||||
x: RADIUS.mobile * Math.cos(rad),
|
||||
y: RADIUS.mobile * Math.sin(rad),
|
||||
}}
|
||||
initial={{ rotate: 0 }}
|
||||
animate={{ rotate: -360 }}
|
||||
transition={{ duration: 60, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
<NodeCard node={node} />
|
||||
</motion.div>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</motion.div>
|
||||
{/* Central Logo Mobile */}
|
||||
<span className="absolute inset-0 m-auto flex size-20 items-center justify-center rounded-full bg-background shadow-[0_12px_30px_rgba(0,0,0,0.1)]">
|
||||
<span aria-hidden className="absolute -inset-4 rounded-full ring-1 ring-border/50" />
|
||||
<span aria-hidden className="absolute -inset-8 rounded-full ring-1 ring-border/30" />
|
||||
{org?.logo ? (
|
||||
<img src={org.logo} alt={org?.name || "Organization"} className="size-[55%] object-contain" />
|
||||
) : (
|
||||
<span className="font-display text-2xl font-black text-foreground">{org?.name ? org.name.charAt(0) : "UN"}</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function NodeCard({ node }: { node: NodeData }) {
|
||||
const content = (
|
||||
<div className="group relative flex cursor-pointer items-center justify-center rounded-full border border-border/60 bg-card/80 p-1.5 shadow-lg backdrop-blur-md transition-all hover:border-brand hover:bg-card">
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-muted text-accent">
|
||||
{node.logo ? (
|
||||
<img src={node.logo} alt={node.name} className="h-6 w-6 object-contain" />
|
||||
) : (
|
||||
<Settings2 className="h-5 w-5" />
|
||||
)}
|
||||
</div>
|
||||
<div className="group relative flex h-full w-full cursor-pointer items-center justify-center transition-transform hover:scale-110">
|
||||
{node.logo ? (
|
||||
<img src={node.logo} alt={node.name} className="size-full object-contain" />
|
||||
) : (
|
||||
<Settings2 className="h-5 w-5 text-muted-foreground" />
|
||||
)}
|
||||
|
||||
{/* Tooltip */}
|
||||
<div className="pointer-events-none absolute -bottom-10 left-1/2 -translate-x-1/2 whitespace-nowrap rounded bg-foreground px-2.5 py-1.5 text-xs font-semibold text-background opacity-0 shadow-xl transition-opacity group-hover:opacity-100">
|
||||
<div className="pointer-events-none absolute -bottom-10 left-1/2 -translate-x-1/2 whitespace-nowrap bg-foreground px-2 py-1 text-[10px] font-bold uppercase tracking-widest text-background opacity-0 shadow-xl transition-opacity group-hover:opacity-100">
|
||||
{node.name}
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,11 +146,11 @@ function NodeCard({ node }: { node: NodeData }) {
|
||||
|
||||
if (node.website_link) {
|
||||
return (
|
||||
<a href={node.website_link} target="_blank" rel="noreferrer" className="block outline-none hover:scale-110 transition-transform">
|
||||
<a href={node.website_link} target="_blank" rel="noreferrer" className="block outline-none hover:-translate-y-1 transition-transform">
|
||||
{content}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className="hover:scale-110 transition-transform">{content}</div>;
|
||||
return <div className="hover:-translate-y-1 transition-transform">{content}</div>;
|
||||
}
|
||||
@@ -13,16 +13,18 @@ export function PageHero({
|
||||
}) {
|
||||
return (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-16 pt-24 md:pb-24 md:pt-32">
|
||||
<Parallax speed={0.06}>
|
||||
<div className="rise flex items-center gap-4 text-xs font-bold uppercase text-brand">
|
||||
<span className="h-px w-12 bg-brand" /> {eyebrow}
|
||||
<div className="mx-auto max-w-7xl px-6 pb-16 pt-32 md:pb-24 md:pt-48">
|
||||
<Parallax speed={0.05}>
|
||||
<div className="rise flex items-center gap-4 text-xs font-bold uppercase tracking-widest text-muted-foreground mb-8">
|
||||
{eyebrow} <span className="h-px w-12 bg-border" />
|
||||
</div>
|
||||
<h1 className="rise-2 mt-7 max-w-5xl text-4xl leading-[1.06] md:text-7xl">
|
||||
{title} {highlight && <span className="text-gradient">{highlight}</span>}
|
||||
<h1 className="rise-2 font-display text-[10vw] sm:text-[8vw] lg:text-[7rem] leading-[0.85] tracking-tighter uppercase mb-16">
|
||||
{title} {highlight && <span className="text-brand block">{highlight}</span>}
|
||||
</h1>
|
||||
<div className="rise-3 mt-8 grid border-t border-border pt-6 md:grid-cols-12">
|
||||
<p className="max-w-2xl text-lg text-muted-foreground md:col-start-6 md:col-span-7">{description}</p>
|
||||
<div className="rise-3 grid grid-cols-1 md:grid-cols-12 gap-8 border-t border-border pt-8">
|
||||
<p className="md:col-start-7 md:col-span-6 text-sm font-medium leading-relaxed text-foreground uppercase tracking-widest">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
@@ -25,18 +25,17 @@ export function TestimonialsMarquee({
|
||||
|
||||
useEffect(() => {
|
||||
if (testimonials.length === 0) return;
|
||||
// We duplicate the array enough times to ensure smooth infinite scroll
|
||||
// A single setWidth is just one set of testimonials
|
||||
const setWidth = testimonials.length * (CARD_WIDTH + GAP);
|
||||
|
||||
controls1.current = animate(x1, [-setWidth, 0], {
|
||||
// Row 1: moves left (0 to -setWidth)
|
||||
controls1.current = animate(x1, [0, -setWidth], {
|
||||
duration: 40,
|
||||
ease: "linear",
|
||||
repeat: Infinity,
|
||||
});
|
||||
|
||||
// Start x2 shifted by half a set width, moving the same direction (left to right)
|
||||
controls2.current = animate(x2, [-setWidth - (setWidth / 2), -setWidth / 2], {
|
||||
// Row 2: moves right (-setWidth to 0)
|
||||
controls2.current = animate(x2, [-setWidth, 0], {
|
||||
duration: 40,
|
||||
ease: "linear",
|
||||
repeat: Infinity,
|
||||
@@ -46,26 +45,21 @@ export function TestimonialsMarquee({
|
||||
controls1.current?.stop();
|
||||
controls2.current?.stop();
|
||||
};
|
||||
}, [testimonials, x1, x2]);
|
||||
}, [testimonials.length, x1, x2]);
|
||||
|
||||
if (testimonials.length === 0) return null;
|
||||
|
||||
// We need enough items to fill the screen twice over to ensure it doesn't run out during animation.
|
||||
const items = [...testimonials, ...testimonials, ...testimonials, ...testimonials, ...testimonials];
|
||||
|
||||
return (
|
||||
<section className="relative z-10 overflow-hidden bg-mist/30 py-24 text-foreground border-y border-border/50">
|
||||
<div className="mx-auto mb-16 max-w-7xl px-6">
|
||||
<div className="flex flex-col justify-between gap-5 md:flex-row md:items-end">
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-accent">Client voices</p>
|
||||
<h2 className="mt-3 text-4xl font-bold">Confidence earned on the ground.</h2>
|
||||
</div>
|
||||
</div>
|
||||
<section className="relative z-10 overflow-hidden bg-background py-32 border-t border-border text-foreground">
|
||||
<div className="mx-auto mb-24 max-w-7xl px-6 text-center">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">Client voices</p>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase md:text-6xl">Confidence earned on the ground.</h2>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="mask-edges relative mx-auto flex flex-col w-full overflow-hidden"
|
||||
className="mask-edges relative mx-auto flex flex-col w-full overflow-hidden gap-6"
|
||||
style={{ overflowAnchor: "none" }}
|
||||
onMouseEnter={() => {
|
||||
controls1.current?.pause();
|
||||
@@ -78,8 +72,8 @@ export function TestimonialsMarquee({
|
||||
>
|
||||
{/* ROW 1 */}
|
||||
<motion.div
|
||||
style={{ x: x1 }}
|
||||
className="flex items-stretch w-max"
|
||||
style={{ x: x1, gap: GAP }}
|
||||
className="flex items-stretch w-max ml-4"
|
||||
>
|
||||
{items.map((t, i) => (
|
||||
<TestimonialCard key={`r1-${t.id}-${i}`} t={t} />
|
||||
@@ -88,8 +82,8 @@ export function TestimonialsMarquee({
|
||||
|
||||
{/* ROW 2 */}
|
||||
<motion.div
|
||||
style={{ x: x2 }}
|
||||
className="flex items-stretch w-max"
|
||||
style={{ x: x2, gap: GAP }}
|
||||
className="flex items-stretch w-max ml-4"
|
||||
>
|
||||
{items.map((t, i) => (
|
||||
<TestimonialCard key={`r2-${t.id}-${i}`} t={t} />
|
||||
@@ -114,31 +108,27 @@ export function TestimonialsMarquee({
|
||||
function TestimonialCard({ t }: { t: Testimonial }) {
|
||||
return (
|
||||
<article
|
||||
className="flex min-h-[260px] w-[480px] shrink-0 flex-col justify-between border border-border/50 bg-card p-8 shadow-sm transition-colors hover:bg-muted/30 m-3 rounded-3xl ml-4"
|
||||
className="flex min-h-[260px] w-[400px] md:w-[480px] shrink-0 flex-col gap-6 border border-border bg-muted/10 p-8 transition-colors hover:bg-muted/30"
|
||||
>
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-6 text-accent">
|
||||
<div className="flex gap-1">
|
||||
{[0, 1, 2, 3, 4].map((star) => <Star key={star} className="h-4 w-4 fill-accent" aria-hidden="true" />)}
|
||||
</div>
|
||||
</div>
|
||||
<blockquote className="text-[17px] font-medium leading-[1.6] tracking-tight text-foreground">
|
||||
{t.testimonial}
|
||||
</blockquote>
|
||||
</div>
|
||||
<footer className="mt-8 flex items-center gap-4">
|
||||
<div className="flex flex-wrap items-center gap-4 border-b border-border/50 pb-6">
|
||||
{t.image ? (
|
||||
<img src={t.image} alt={t.name} className="h-11 w-11 rounded-lg object-cover ring-1 ring-border/50" />
|
||||
<img src={t.image} alt={t.name} className="h-12 w-12 rounded-full object-cover grayscale" />
|
||||
) : (
|
||||
<div className="grid h-11 w-11 place-items-center rounded-lg bg-muted ring-1 ring-border/50 text-lg font-bold text-muted-foreground">
|
||||
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-foreground font-display text-lg font-bold text-background">
|
||||
{t.name.charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<p className="text-[15px] font-semibold text-foreground">{t.name}</p>
|
||||
<p className="text-[13px] text-muted-foreground">{t.organization}</p>
|
||||
<div className="flex min-w-[150px] flex-1 flex-col gap-1">
|
||||
<p className="text-base font-bold uppercase tracking-wide text-foreground">{t.name}</p>
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-muted-foreground">{t.organization || "Google review"}</p>
|
||||
</div>
|
||||
</footer>
|
||||
<div className="ml-auto flex gap-1">
|
||||
{[0, 1, 2, 3, 4].map((star) => <Star key={star} className="h-4 w-4 fill-foreground text-foreground" aria-hidden="true" />)}
|
||||
</div>
|
||||
</div>
|
||||
<blockquote className="text-lg font-medium leading-relaxed text-muted-foreground">
|
||||
"{t.testimonial}"
|
||||
</blockquote>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
@@ -67,25 +67,23 @@ function About() {
|
||||
|
||||
{about && (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto grid max-w-7xl items-center gap-12 px-6 pb-24 lg:grid-cols-12">
|
||||
<div className="mx-auto grid max-w-7xl items-center gap-16 px-6 pb-32 lg:grid-cols-12">
|
||||
<div className="lg:col-span-5">
|
||||
<Parallax speed={0.1}>
|
||||
<div className="group overflow-hidden rounded-3xl border border-border/50 bg-card p-2 shadow-2xl transition-all hover:shadow-brand/10">
|
||||
<div className="group overflow-hidden bg-muted aspect-[4/5] w-full">
|
||||
<img
|
||||
src={about.cover_image }
|
||||
src={about.cover_image}
|
||||
loading="lazy"
|
||||
width={1024}
|
||||
height={1152}
|
||||
alt={about.title}
|
||||
className="aspect-[4/5] w-full rounded-2xl object-cover transition duration-700 group-hover:scale-105"
|
||||
className="w-full h-full object-cover grayscale transition duration-1000 group-hover:grayscale-0 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
</Parallax>
|
||||
</div>
|
||||
<div className="lg:col-span-7">
|
||||
<div className="lg:col-span-7 lg:pl-12">
|
||||
<Reveal>
|
||||
<h2 className="text-4xl font-black tracking-tight md:text-5xl">{about.title}</h2>
|
||||
<div className="mt-5 text-muted-foreground prose prose-invert" dangerouslySetInnerHTML={{ __html: about.about_us }} />
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase md:text-6xl">{about.title}</h2>
|
||||
<div className="mt-8 text-base leading-relaxed text-muted-foreground prose prose-invert max-w-2xl" dangerouslySetInnerHTML={{ __html: about.about_us }} />
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -93,90 +91,65 @@ function About() {
|
||||
)}
|
||||
|
||||
{vision && (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-24">
|
||||
<section className="relative z-10 border-t border-border mt-16 pt-32">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32">
|
||||
<Reveal>
|
||||
<p className="inline-flex items-center gap-2 rounded-full bg-brand/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-brand">Vision</p>
|
||||
<h2 className="mt-3 text-4xl font-black tracking-tight md:text-5xl">{vision.title}</h2>
|
||||
</Reveal>
|
||||
<div className="mt-10 grid items-center gap-10 lg:grid-cols-12">
|
||||
<div className="lg:col-span-7">
|
||||
<Reveal>
|
||||
<div className="border-l-4 border-brand bg-mist p-10">
|
||||
<span className="inline-flex h-12 w-12 items-center justify-center border border-brand/30 bg-background text-brand">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>
|
||||
</span>
|
||||
<div className="mt-6 text-xl font-medium leading-relaxed md:text-2xl prose prose-invert" dangerouslySetInnerHTML={{ __html: vision.vision }} />
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
{vision.subtitle && (
|
||||
<div className="lg:col-span-5">
|
||||
<Parallax speed={0.08}>
|
||||
<Reveal delay={100}>
|
||||
<p className="text-muted-foreground">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||||
<div className="lg:col-span-4">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">01 — Vision</p>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase">{vision.title}</h2>
|
||||
{vision.subtitle && (
|
||||
<p className="mt-6 text-sm font-medium text-foreground uppercase tracking-widest">
|
||||
{vision.subtitle}
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
)}
|
||||
</div>
|
||||
<div className="lg:col-span-8 lg:pl-12">
|
||||
<div className="text-2xl md:text-4xl font-display font-bold uppercase tracking-tight leading-tight text-foreground/80 prose prose-invert" dangerouslySetInnerHTML={{ __html: vision.vision }} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{mision && (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-24">
|
||||
<section className="relative z-10 border-t border-border pt-32">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32">
|
||||
<Reveal>
|
||||
<p className="inline-flex items-center gap-2 rounded-full bg-brand/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-brand">Mission</p>
|
||||
<h2 className="mt-3 text-4xl font-black tracking-tight md:text-5xl">{mision.title}</h2>
|
||||
</Reveal>
|
||||
<div className="mt-10 grid items-center gap-10 lg:grid-cols-12">
|
||||
{mision.subtitle && (
|
||||
<div className="order-2 lg:order-1 lg:col-span-5">
|
||||
<Parallax speed={0.06}>
|
||||
<Reveal delay={100}>
|
||||
<p className="text-muted-foreground">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
|
||||
<div className="lg:col-span-4">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">02 — Mission</p>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase">{mision.title}</h2>
|
||||
{mision.subtitle && (
|
||||
<p className="mt-6 text-sm font-medium text-foreground uppercase tracking-widest">
|
||||
{mision.subtitle}
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
)}
|
||||
</div>
|
||||
<div className="lg:col-span-8 lg:pl-12">
|
||||
<div className="text-2xl md:text-4xl font-display font-bold uppercase tracking-tight leading-tight text-foreground/80 prose prose-invert" dangerouslySetInnerHTML={{ __html: mision.mision }} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="order-1 lg:order-2 lg:col-span-7">
|
||||
<Reveal>
|
||||
<div className="border-r-4 border-brand bg-mist p-10">
|
||||
<span className="inline-flex h-12 w-12 items-center justify-center border border-brand/30 bg-background text-brand">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
|
||||
</span>
|
||||
<div className="mt-6 text-xl font-medium leading-relaxed md:text-2xl prose prose-invert" dangerouslySetInnerHTML={{ __html: mision.mision }} />
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{values && values.length > 0 && (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-24">
|
||||
<section className="relative z-10 border-t border-border pt-32">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32">
|
||||
<Reveal>
|
||||
<p className="inline-flex items-center gap-2 rounded-full bg-brand/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-brand">Values</p>
|
||||
<h2 className="mt-3 text-4xl font-black tracking-tight md:text-5xl">What we stand for</h2>
|
||||
<p className="mt-4 max-w-2xl text-muted-foreground">
|
||||
The principles behind every machine we export, manufacture and supply.
|
||||
</p>
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">03 — Values</p>
|
||||
<h2 className="text-5xl font-display font-black tracking-tighter uppercase md:text-7xl">What we stand for.</h2>
|
||||
</Reveal>
|
||||
<div className="mt-10 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div className="mt-24 grid gap-16 md:grid-cols-2 lg:grid-cols-4">
|
||||
{values.map((val, index) => (
|
||||
<Reveal key={val.id} delay={index * 80}>
|
||||
<div className="h-full border-t-2 border-brand bg-mist p-8">
|
||||
<span className="text-4xl font-bold text-brand/30">{String(index + 1).padStart(2, "0")}</span>
|
||||
<h3 className="mt-4 text-lg font-bold">{val.title}</h3>
|
||||
<div className="mt-3 text-sm leading-relaxed text-muted-foreground prose prose-invert" dangerouslySetInnerHTML={{ __html: val.values }} />
|
||||
<div className="border-t-2 border-foreground pt-8">
|
||||
<span className="text-4xl font-display font-black text-muted-foreground">{String(index + 1).padStart(2, "0")}</span>
|
||||
<h3 className="mt-6 text-xl font-display font-black uppercase tracking-tight">{val.title}</h3>
|
||||
<div className="mt-4 text-sm font-medium leading-relaxed text-muted-foreground prose prose-invert" dangerouslySetInnerHTML={{ __html: val.values }} />
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
|
||||
@@ -32,22 +32,22 @@ function Career() {
|
||||
description="We hire people who care about the details — precise hands, clear communication and a habit of finishing the job."
|
||||
/>
|
||||
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-24">
|
||||
<div className="divide-y divide-border overflow-hidden border-y border-border bg-background">
|
||||
<section className="relative z-10 border-t border-border mt-16 pt-16">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32">
|
||||
<div className="flex flex-col gap-0 border-t-2 border-foreground">
|
||||
{roles?.map((role, i) => (
|
||||
<Reveal key={role.id} delay={i * 70}>
|
||||
<div className="flex flex-wrap items-center justify-between gap-4 p-7">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold">{role.name}</h2>
|
||||
<p className="mt-1 text-xs font-semibold uppercase tracking-[0.15em] text-accent">
|
||||
{role.job_time} · {role.location}
|
||||
<div className="flex flex-wrap items-start md:items-center justify-between gap-8 py-10 border-b border-border hover:bg-muted/30 transition-colors">
|
||||
<div className="flex-1">
|
||||
<p className="mb-4 text-xs font-bold uppercase tracking-widest text-muted-foreground">
|
||||
{role.job_time} <span className="mx-2">—</span> {role.location}
|
||||
</p>
|
||||
<p className="mt-2 max-w-lg text-sm text-muted-foreground">{role.short_info}</p>
|
||||
<h2 className="text-3xl font-display font-black tracking-tighter uppercase">{role.name}</h2>
|
||||
<p className="mt-4 max-w-lg text-sm font-medium leading-relaxed text-muted-foreground">{role.short_info}</p>
|
||||
</div>
|
||||
<Link
|
||||
to={`/career/${role.id}`}
|
||||
className="bg-ink px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-brand"
|
||||
className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-background bg-foreground px-8 py-4 hover:bg-foreground/80 transition-colors shrink-0"
|
||||
>
|
||||
View role
|
||||
</Link>
|
||||
@@ -55,7 +55,7 @@ function Career() {
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
<p className="mt-8 text-sm text-muted-foreground">
|
||||
<p className="mt-12 text-sm font-bold uppercase tracking-widest text-muted-foreground">
|
||||
Don't see your role? Send your CV through the contact page and we'll keep it on file.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -70,27 +70,27 @@ export default function Contact() {
|
||||
<Reveal className="order-2 lg:order-1 lg:col-span-7">
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="flex flex-col gap-6 rounded-2xl border border-border bg-card p-8 shadow-lg md:p-12"
|
||||
className="flex flex-col gap-8 border-t-2 border-foreground pt-12"
|
||||
>
|
||||
<div className="mb-2">
|
||||
<h3 className="text-2xl font-bold text-foreground">Send an enquiry</h3>
|
||||
<p className="mt-2 text-sm text-muted-foreground">We generally respond within 24 hours.</p>
|
||||
<div className="mb-4">
|
||||
<h3 className="text-4xl font-display font-black tracking-tighter uppercase text-foreground">Send an enquiry</h3>
|
||||
<p className="mt-4 text-xs font-bold uppercase tracking-widest text-muted-foreground">We generally respond within 24 hours.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
<div className="grid gap-8 sm:grid-cols-2">
|
||||
<div className="space-y-4">
|
||||
<label className="text-xs font-bold uppercase tracking-widest text-foreground">
|
||||
Full Name
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
name="name"
|
||||
placeholder="John Doe"
|
||||
className="w-full rounded-xl border border-border bg-background px-4 py-3.5 text-sm text-foreground outline-none transition placeholder:text-muted-foreground/50 focus:border-brand focus:bg-background focus:ring-1 focus:ring-brand"
|
||||
className="w-full border-b border-border bg-transparent px-0 py-3 text-base text-foreground outline-none transition placeholder:text-muted-foreground/30 focus:border-foreground"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
<div className="space-y-4">
|
||||
<label className="text-xs font-bold uppercase tracking-widest text-foreground">
|
||||
Phone Number
|
||||
</label>
|
||||
<input
|
||||
@@ -98,14 +98,14 @@ export default function Contact() {
|
||||
name="phone_no"
|
||||
type="tel"
|
||||
placeholder="+977 98..."
|
||||
className="w-full rounded-xl border border-border bg-background px-4 py-3.5 text-sm text-foreground outline-none transition placeholder:text-muted-foreground/50 focus:border-brand focus:bg-background focus:ring-1 focus:ring-brand"
|
||||
className="w-full border-b border-border bg-transparent px-0 py-3 text-base text-foreground outline-none transition placeholder:text-muted-foreground/30 focus:border-foreground"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-6 sm:grid-cols-2">
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
<div className="grid gap-8 sm:grid-cols-2">
|
||||
<div className="space-y-4">
|
||||
<label className="text-xs font-bold uppercase tracking-widest text-foreground">
|
||||
Email Address
|
||||
</label>
|
||||
<input
|
||||
@@ -113,53 +113,52 @@ export default function Contact() {
|
||||
name="email"
|
||||
type="email"
|
||||
placeholder="john@example.com"
|
||||
className="w-full rounded-xl border border-border bg-background px-4 py-3.5 text-sm text-foreground outline-none transition placeholder:text-muted-foreground/50 focus:border-brand focus:bg-background focus:ring-1 focus:ring-brand"
|
||||
className="w-full border-b border-border bg-transparent px-0 py-3 text-base text-foreground outline-none transition placeholder:text-muted-foreground/30 focus:border-foreground"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
<div className="space-y-4">
|
||||
<label className="text-xs font-bold uppercase tracking-widest text-foreground">
|
||||
Subject
|
||||
</label>
|
||||
<input
|
||||
required
|
||||
name="subject"
|
||||
placeholder="Machinery Quote"
|
||||
className="w-full rounded-xl border border-border bg-background px-4 py-3.5 text-sm text-foreground outline-none transition placeholder:text-muted-foreground/50 focus:border-brand focus:bg-background focus:ring-1 focus:ring-brand"
|
||||
className="w-full border-b border-border bg-transparent px-0 py-3 text-base text-foreground outline-none transition placeholder:text-muted-foreground/30 focus:border-foreground"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
<div className="space-y-4">
|
||||
<label className="text-xs font-bold uppercase tracking-widest text-foreground">
|
||||
What are you looking for?
|
||||
</label>
|
||||
<textarea
|
||||
required
|
||||
name="message"
|
||||
rows={5}
|
||||
rows={4}
|
||||
placeholder="Tell us about your requirements..."
|
||||
className="w-full resize-none rounded-xl border border-border bg-background px-4 py-3.5 text-sm text-foreground outline-none transition placeholder:text-muted-foreground/50 focus:border-brand focus:bg-background focus:ring-1 focus:ring-brand"
|
||||
className="w-full resize-none border-b border-border bg-transparent px-0 py-3 text-base text-foreground outline-none transition placeholder:text-muted-foreground/30 focus:border-foreground"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
<button
|
||||
type="submit"
|
||||
size="lg"
|
||||
className="mt-2 h-14 w-full rounded-xl bg-brand text-base font-bold shadow-lg shadow-brand/20 transition-all hover:scale-[1.02] hover:bg-brand/90"
|
||||
className="mt-6 inline-flex self-start items-center gap-2 text-sm font-bold uppercase tracking-widest text-background bg-foreground px-8 py-4 hover:bg-foreground/80 transition-colors"
|
||||
>
|
||||
Send Enquiry
|
||||
</Button>
|
||||
</button>
|
||||
|
||||
{sent && (
|
||||
<div className="mt-2 rounded-lg bg-green-50 p-4 text-center border border-green-200 dark:bg-green-500/10 dark:border-green-500/20">
|
||||
<p className="text-sm font-semibold text-green-600 dark:text-green-400">
|
||||
<div className="mt-4 border border-border p-6 text-center">
|
||||
<p className="text-sm font-bold uppercase tracking-widest text-foreground">
|
||||
Thanks — your enquiry has been sent successfully. We will get back to you shortly.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{error && (
|
||||
<div className="mt-2 rounded-lg bg-red-50 p-4 text-center border border-red-200 dark:bg-red-500/10 dark:border-red-500/20">
|
||||
<p className="text-sm font-semibold text-red-600 dark:text-red-400">
|
||||
<div className="mt-4 border border-border p-6 text-center">
|
||||
<p className="text-sm font-bold uppercase tracking-widest text-red-600">
|
||||
There was an error sending your message. Please try again later.
|
||||
</p>
|
||||
</div>
|
||||
@@ -170,72 +169,52 @@ export default function Contact() {
|
||||
{/* Contact Info Sidebar */}
|
||||
{org && (
|
||||
<Reveal delay={90} className="order-1 lg:order-2 lg:col-span-5">
|
||||
<div className="flex h-full flex-col justify-center space-y-10 rounded-2xl border border-border bg-card p-8 shadow-lg md:p-12">
|
||||
<div className="flex flex-col justify-start space-y-16 border-t-2 border-border pt-12">
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold text-foreground">{org.name || "Udhamsil Nepal"}</h2>
|
||||
<p className="mt-2 text-sm font-semibold uppercase tracking-[0.2em] text-accent">
|
||||
<h2 className="text-3xl font-display font-black tracking-tight uppercase text-foreground">{org.name || "Udhamsil"}</h2>
|
||||
<p className="mt-2 text-xs font-bold uppercase tracking-widest text-muted-foreground">
|
||||
Global Trade Company
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="mt-1 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-brand">
|
||||
<MapPin className="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-foreground">Headquarters</h3>
|
||||
<p className="mt-1 text-sm leading-relaxed text-muted-foreground whitespace-pre-line">
|
||||
{org.address || "Kohalpur-11, Banke\nLumbini Province, Nepal"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-12">
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4 border-b border-border pb-2">Headquarters</h3>
|
||||
<p className="text-sm font-medium leading-relaxed text-foreground whitespace-pre-line">
|
||||
{org.address || "Kohalpur-11, Banke\nLumbini Province, Nepal"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="mt-1 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-brand">
|
||||
<Mail className="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-foreground">Email Us</h3>
|
||||
<a href={`mailto:${org.primary_email || "info@udhamsilnepal.com"}`} className="mt-1 block text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
{org.primary_email || "info@udhamsilnepal.com"}
|
||||
</a>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4 border-b border-border pb-2">Email Us</h3>
|
||||
<a href={`mailto:${org.primary_email || "info@udhamsilnepal.com"}`} className="block text-sm font-medium text-foreground hover:text-brand transition-colors">
|
||||
{org.primary_email || "info@udhamsilnepal.com"}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{(org.phone_number || org.whatsapp_no) && (
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="mt-1 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-brand">
|
||||
<Phone className="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-foreground">Call Us</h3>
|
||||
<div className="mt-1 space-y-1">
|
||||
{org.phone_number && (
|
||||
<a href={`tel:${org.phone_number}`} className="block text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
{org.phone_number}
|
||||
</a>
|
||||
)}
|
||||
{org.whatsapp_no && (
|
||||
<a href={`https://wa.me/${org.whatsapp_no}`} target="_blank" rel="noreferrer" className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
<MessageSquare className="h-3.5 w-3.5" /> WhatsApp: {org.whatsapp_no}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4 border-b border-border pb-2">Call Us</h3>
|
||||
<div className="space-y-2">
|
||||
{org.phone_number && (
|
||||
<a href={`tel:${org.phone_number}`} className="block text-sm font-medium text-foreground hover:text-brand transition-colors">
|
||||
{org.phone_number}
|
||||
</a>
|
||||
)}
|
||||
{org.whatsapp_no && (
|
||||
<a href={`https://wa.me/${org.whatsapp_no}`} target="_blank" rel="noreferrer" className="block text-sm font-medium text-foreground hover:text-brand transition-colors">
|
||||
WhatsApp: {org.whatsapp_no}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="mt-1 flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-brand">
|
||||
<Clock className="h-5 w-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-foreground">Business Hours</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{org.working_hour || "Sunday – Friday, 9:00 – 18:00"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4 border-b border-border pb-2">Business Hours</h3>
|
||||
<p className="text-sm font-medium text-foreground">
|
||||
{org.working_hour || "Sunday – Friday, 9:00 – 18:00"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -247,7 +226,7 @@ export default function Contact() {
|
||||
{(org?.google_map_link || org?.address) && (
|
||||
<Reveal delay={180}>
|
||||
<div className="mx-auto max-w-7xl px-6 pb-24">
|
||||
<div className="h-[400px] w-full overflow-hidden rounded-2xl border border-border shadow-lg">
|
||||
<div className="h-[500px] w-full overflow-hidden bg-muted grayscale">
|
||||
<iframe
|
||||
title="Google Maps"
|
||||
src={org?.google_map_link && org.google_map_link.includes("embed") ? org.google_map_link : `https://www.google.com/maps?q=${encodeURIComponent(org?.address || "")}&output=embed`}
|
||||
|
||||
+165
-174
@@ -2,7 +2,6 @@ import { Link } from "react-router-dom";
|
||||
import { Star, ArrowRight } from "lucide-react";
|
||||
import { LightField, Parallax, Reveal } from "@/components/site/Parallax";
|
||||
import { OrbitalVisualization } from "@/components/site/OrbitalVisualization";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ClientsMarquee } from "@/components/site/ClientsMarquee";
|
||||
import { TestimonialsMarquee } from "@/components/site/TestimonialsMarquee";
|
||||
import { useApi } from "@/hooks/useApi";
|
||||
@@ -33,150 +32,148 @@ function Index() {
|
||||
<LightField />
|
||||
|
||||
{hero && (
|
||||
<section className="relative z-10 overflow-hidden">
|
||||
<div className="mx-auto grid min-h-[720px] max-w-7xl items-center gap-12 px-6 py-16 lg:grid-cols-12 lg:py-24">
|
||||
<div className="lg:col-span-6">
|
||||
<div className="rise inline-flex items-center gap-3 rounded-full bg-brand/10 px-4 py-1.5 text-xs font-bold uppercase tracking-wider text-brand">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-brand opacity-75"></span>
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-brand"></span>
|
||||
</span>
|
||||
{hero.eyebrow || "Est. 2020 · Kohalpur, Banke"}
|
||||
<section className="relative z-10 overflow-hidden pt-32 pb-24">
|
||||
<div className="mx-auto max-w-7xl px-6">
|
||||
<div className="grid lg:grid-cols-12 gap-12 items-end mb-16">
|
||||
<div className="lg:col-span-9 rise">
|
||||
<h1 className="font-display text-[12vw] sm:text-[8vw] lg:text-[6rem] leading-[0.85] tracking-tighter uppercase">
|
||||
{hero.title || "Machinery built for"} <br />
|
||||
<span className="text-brand">{hero.highlight || "Nepal."}</span>
|
||||
</h1>
|
||||
</div>
|
||||
<h1 className="rise-2 mt-8 text-5xl font-black leading-[1.05] tracking-tight md:text-7xl">
|
||||
{hero.title || "Machinery built for"} <span className="text-gradient">{hero.highlight || "Nepal."}</span>
|
||||
</h1>
|
||||
<p className="rise-3 mt-7 max-w-xl text-lg md:text-xl leading-relaxed text-muted-foreground">
|
||||
{hero.description || "Reliable, innovative machinery solutions — exporting, manufacturing, distributing and supplying small, medium and commercial scale equipment across the nation."}
|
||||
</p>
|
||||
<div className="rise-3 mt-10 flex flex-wrap gap-4">
|
||||
<Button asChild size="lg" className="h-14 rounded-full bg-brand px-8 text-base shadow-lg shadow-brand/20 transition-all hover:scale-105 hover:bg-brand/90">
|
||||
<Link to="/products">Explore Products</Link>
|
||||
</Button>
|
||||
<Button asChild size="lg" variant="outline" className="h-14 rounded-full bg-background px-8 text-base border-border/50 hover:bg-muted transition-all hover:scale-105">
|
||||
<Link to="/projects-events">View Projects</Link>
|
||||
</Button>
|
||||
</div>
|
||||
{stats.length > 0 && (
|
||||
<div className="rise-3 mt-16 grid max-w-xl grid-cols-3 gap-6 border-t border-border/40 pt-8">
|
||||
{stats.map((st) => (
|
||||
<div key={st.id} className="group">
|
||||
<p className="font-display text-3xl font-black tracking-tight text-foreground transition-colors group-hover:text-brand">{st.stats}{st.title.includes('delivery') ? '%' : '+'}</p>
|
||||
<p className="mt-1 text-sm font-medium text-muted-foreground">{st.title}</p>
|
||||
</div>
|
||||
))}
|
||||
<div className="lg:col-span-3 pb-4 rise-2">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground border-b border-border pb-4 mb-4">
|
||||
{hero.eyebrow || "Est. 2020 · Kohalpur, Banke"}
|
||||
</p>
|
||||
<p className="text-sm font-medium leading-relaxed text-foreground">
|
||||
{hero.description || "Reliable, innovative machinery solutions — exporting, manufacturing, distributing and supplying small, medium and commercial scale equipment across the nation."}
|
||||
</p>
|
||||
<div className="mt-8 flex flex-col gap-3">
|
||||
<Link to="/products" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-foreground hover:text-brand transition-colors">
|
||||
Explore Products <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
<Link to="/contact" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-muted-foreground hover:text-foreground transition-colors">
|
||||
Get a Quote <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative min-h-[480px] lg:col-span-6">
|
||||
<div className="absolute inset-0 right-0 md:left-10">
|
||||
<Parallax speed={0.06}>
|
||||
<div className="group relative overflow-hidden rounded-3xl border border-border/40 bg-card p-2 shadow-2xl transition-all hover:shadow-brand/10">
|
||||
<img
|
||||
src={hero.image}
|
||||
width={1024}
|
||||
height={1280}
|
||||
alt="Featured equipment"
|
||||
className="h-[440px] w-full rounded-2xl object-cover transition duration-700 group-hover:scale-105 md:h-[580px]"
|
||||
/>
|
||||
<div className="absolute inset-x-4 bottom-4 flex items-end justify-between rounded-xl bg-ink/90 p-6 text-primary-foreground backdrop-blur-md">
|
||||
<div>
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-primary-foreground/60">Featured equipment</p>
|
||||
<p className="mt-2 font-display text-xl font-bold">{hero.featured_text || "Commercial systems"}</p>
|
||||
</div>
|
||||
<span className="font-display text-4xl font-black text-accent opacity-50">01</span>
|
||||
</div>
|
||||
</div>
|
||||
</Parallax>
|
||||
<div className="relative w-full aspect-[4/3] md:aspect-[21/9] bg-muted overflow-hidden rise-3">
|
||||
<Parallax speed={0.05}>
|
||||
<img
|
||||
src={hero.image}
|
||||
alt="Featured equipment"
|
||||
className="w-full h-full object-cover object-center scale-110"
|
||||
/>
|
||||
</Parallax>
|
||||
<div className="absolute inset-x-6 bottom-6 flex items-end justify-between">
|
||||
<div>
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-white mix-blend-difference">Featured equipment</p>
|
||||
<p className="mt-1 font-display text-lg text-white mix-blend-difference">{hero.featured_text || "Commercial systems"}</p>
|
||||
</div>
|
||||
<span className="font-display text-2xl font-black text-white mix-blend-difference opacity-50">01</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{stats.length > 0 && (
|
||||
<div className="mt-24 grid grid-cols-2 md:grid-cols-4 gap-8 border-t border-border pt-8 rise-3">
|
||||
{stats.map((st) => (
|
||||
<div key={st.id}>
|
||||
<p className="font-display text-4xl md:text-5xl font-black tracking-tighter">{st.stats}{st.title.includes('delivery') ? '%' : '+'}</p>
|
||||
<p className="mt-2 text-xs font-bold uppercase tracking-widest text-muted-foreground">{st.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{marquee.length > 0 && (
|
||||
<div className="relative z-10 flex overflow-hidden border-y border-border bg-card py-6">
|
||||
<div className="animate-marquee flex whitespace-nowrap">
|
||||
{[0, 1, 2, 3].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex items-center gap-12 pr-12 text-xl font-black uppercase tracking-[0.1em] text-foreground md:text-2xl"
|
||||
>
|
||||
{marquee.map((m) => (
|
||||
<span key={m.id} className="flex items-center gap-12">
|
||||
<span>{m.title}</span>
|
||||
<Star className="h-6 w-6 fill-brand text-brand" />
|
||||
</span>
|
||||
))}
|
||||
<section className="relative z-10 border-t border-border mt-16 pt-32 pb-16">
|
||||
<div className="mx-auto max-w-7xl px-6">
|
||||
<Reveal>
|
||||
<div className="mb-16">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">Capabilities</p>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase md:text-6xl">What we do at scale.</h2>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{partners.length > 0 && (
|
||||
<section className="relative z-10 overflow-hidden border-b border-border bg-mist/30">
|
||||
<div className="mx-auto grid max-w-7xl items-center gap-14 px-6 py-24 lg:grid-cols-12">
|
||||
<div className="lg:col-span-5">
|
||||
<Reveal>
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-accent">
|
||||
Our clients
|
||||
</div>
|
||||
<h2 className="mt-6 text-4xl font-black tracking-tight md:text-5xl">Built around the people who produce.</h2>
|
||||
<p className="mt-6 max-w-lg text-lg leading-relaxed text-muted-foreground">
|
||||
We work with ambitious enterprises across agriculture, food production, construction,
|
||||
utilities and commercial manufacturing.
|
||||
</p>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
<div className="lg:col-span-7">
|
||||
<Parallax speed={0.04}>
|
||||
<div>
|
||||
<ClientsMarquee partners={partners} />
|
||||
</div>
|
||||
</Parallax>
|
||||
</Reveal>
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 auto-rows-[200px] md:auto-rows-[250px]">
|
||||
{marquee.map((m, i) => {
|
||||
const bentoClasses = [
|
||||
"md:col-span-2 lg:col-span-2",
|
||||
"md:col-span-2 lg:col-span-2",
|
||||
"md:col-span-4 lg:col-span-2",
|
||||
"md:col-span-2 lg:col-span-1",
|
||||
"md:col-span-2 lg:col-span-1"
|
||||
];
|
||||
const spanClass = bentoClasses[i % bentoClasses.length];
|
||||
|
||||
return (
|
||||
<Reveal key={m.id} delay={i * 50} className={`${spanClass} bg-muted p-8 flex flex-col justify-between group overflow-hidden relative border border-border/50`}>
|
||||
<div className="absolute inset-0 bg-foreground translate-y-full group-hover:translate-y-0 transition-transform duration-700 ease-in-out" />
|
||||
<span className="relative z-10 text-2xl font-display font-black text-muted-foreground/30 group-hover:text-background/30 transition-colors duration-700">0{i + 1}</span>
|
||||
<h3 className="relative z-10 text-3xl md:text-4xl lg:text-5xl font-display font-black uppercase tracking-tight text-foreground group-hover:text-background transition-colors duration-700 break-words">{m.title}</h3>
|
||||
</Reveal>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{whatWeDo.length > 0 && (
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32">
|
||||
<div className="mb-16 flex flex-col items-start justify-between gap-6 md:flex-row md:items-end">
|
||||
<div>
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-accent">
|
||||
What we do
|
||||
</div>
|
||||
<h2 className="mt-6 text-4xl font-black tracking-tight md:text-5xl">Machinery, end to end</h2>
|
||||
{partners.length > 0 && (
|
||||
<section className="relative z-10 w-full pt-32 pb-16 overflow-hidden">
|
||||
{/* Centered pill on horizontal line */}
|
||||
<div className="relative flex items-center justify-center">
|
||||
<div className="absolute w-full h-px bg-border"></div>
|
||||
<div className="relative z-10 bg-background px-4">
|
||||
<div className="rounded-full bg-muted/30 border border-border/50 px-6 py-2 text-sm font-semibold tracking-wide text-foreground">
|
||||
Our partners
|
||||
</div>
|
||||
<Button asChild variant="ghost" className="rounded-full font-bold text-brand hover:bg-brand/10 hover:text-brand">
|
||||
<Link to="/products" className="flex items-center gap-2">
|
||||
See all products <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="grid gap-8 md:grid-cols-3">
|
||||
</div>
|
||||
|
||||
{/* Marquee below */}
|
||||
<div className="mx-auto w-full max-w-[1600px] mt-16 px-4">
|
||||
<ClientsMarquee partners={partners} />
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{whatWeDo.length > 0 && (
|
||||
<section className="relative z-10 border-t border-border mt-24">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32">
|
||||
<div className="mb-24 flex flex-col items-start gap-6 md:flex-row md:items-end md:justify-between">
|
||||
<div>
|
||||
<h2 className="text-5xl font-display font-black tracking-tighter uppercase md:text-7xl">Machinery,<br />end to end.</h2>
|
||||
</div>
|
||||
<Link to="/products" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-foreground hover:text-brand transition-colors">
|
||||
See all products <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-24">
|
||||
{whatWeDo.map((c, i) => (
|
||||
<Reveal key={c.id} delay={i * 90}>
|
||||
<div className="group flex h-full flex-col overflow-hidden rounded-3xl border border-border/50 bg-card shadow-lg transition-all hover:-translate-y-1 hover:shadow-xl hover:shadow-brand/5">
|
||||
{c.cover_image && (
|
||||
<div className="overflow-hidden">
|
||||
<img
|
||||
src={c.cover_image}
|
||||
loading="lazy"
|
||||
width={1024}
|
||||
height={768}
|
||||
alt={c.title}
|
||||
className="aspect-[4/3] w-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-1 flex-col p-8">
|
||||
<h3 className="text-2xl font-bold tracking-tight text-foreground">{c.title}</h3>
|
||||
<div className="mt-4 text-muted-foreground prose prose-invert line-clamp-4" dangerouslySetInnerHTML={{ __html: c.what_we_do }} />
|
||||
<Reveal key={c.id} delay={i * 50}>
|
||||
<div className={`grid gap-12 items-center lg:grid-cols-12 ${i % 2 !== 0 ? 'lg:rtl' : ''}`}>
|
||||
<div className={`lg:col-span-7 ${i % 2 !== 0 ? 'lg:ltr' : ''}`}>
|
||||
{c.cover_image && (
|
||||
<div className="overflow-hidden aspect-[4/3] bg-muted">
|
||||
<img
|
||||
src={c.cover_image}
|
||||
loading="lazy"
|
||||
alt={c.title}
|
||||
className="w-full h-full object-cover grayscale hover:grayscale-0 transition-all duration-700"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`lg:col-span-5 ${i % 2 !== 0 ? 'lg:ltr' : ''}`}>
|
||||
<span className="font-display text-4xl font-black text-brand/20">{(i + 1).toString().padStart(2, "0")}</span>
|
||||
<h3 className="mt-4 text-3xl font-display font-black uppercase tracking-tight">{c.title}</h3>
|
||||
<div className="mt-6 text-base leading-relaxed text-muted-foreground prose prose-invert" dangerouslySetInnerHTML={{ __html: c.what_we_do }} />
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
@@ -187,46 +184,48 @@ function Index() {
|
||||
)}
|
||||
|
||||
{services.length > 0 && (
|
||||
<section className="relative z-10 border-y border-border bg-mist/30">
|
||||
<section className="relative z-10 border-t border-border">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32">
|
||||
<Reveal>
|
||||
<div className="grid gap-8 md:grid-cols-[1fr_1.5fr] md:items-end">
|
||||
<div>
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-accent">
|
||||
Why Udhamsil
|
||||
</div>
|
||||
<h2 className="mt-6 text-4xl font-black tracking-tight md:text-5xl">From requirement to reliable output.</h2>
|
||||
<div className="grid gap-12 lg:grid-cols-12 lg:items-start">
|
||||
<div className="lg:col-span-5">
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase md:text-5xl">From requirement<br />to reliable output.</h2>
|
||||
<p className="mt-6 max-w-sm text-sm font-medium leading-relaxed text-muted-foreground uppercase tracking-widest">
|
||||
One accountable team helps you choose, receive and keep the right machinery running.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="lg:col-span-7">
|
||||
<div className="flex flex-col gap-0 border-t border-border">
|
||||
{services.map((step, index) => (
|
||||
<Reveal key={step.id} delay={index * 50}>
|
||||
<div className="group grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-6 sm:gap-12 py-10 border-b border-border transition-colors hover:bg-muted/30">
|
||||
<span className="font-display text-lg font-black text-muted-foreground">{(index + 1).toString().padStart(2, "0")} —</span>
|
||||
<div>
|
||||
<h3 className="text-2xl font-display font-black tracking-tight uppercase group-hover:text-brand transition-colors">{step.name}</h3>
|
||||
<div className="mt-4 text-base leading-relaxed text-muted-foreground prose prose-invert max-w-xl" dangerouslySetInnerHTML={{ __html: step.description }} />
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-muted-foreground md:justify-self-end">
|
||||
One accountable team helps you choose, receive and keep the right machinery running.
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{services.map((step, index) => (
|
||||
<Reveal key={step.id} delay={index * 70}>
|
||||
<div className="group relative flex h-full flex-col rounded-3xl border border-border/50 bg-card p-8 shadow-lg transition-all hover:border-brand/30 hover:bg-muted/50">
|
||||
<span className="font-display text-5xl font-black text-brand/10 transition-colors group-hover:text-brand/20">{(index + 1).toString().padStart(2, "0")}</span>
|
||||
<h3 className="mt-6 text-xl font-bold tracking-tight">{step.name}</h3>
|
||||
<div className="mt-4 text-sm leading-relaxed text-muted-foreground prose prose-invert" dangerouslySetInnerHTML={{ __html: step.description }} />
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{sisterCompanies.length > 0 && (
|
||||
<section className="relative z-10 overflow-hidden bg-background">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32">
|
||||
<section className="relative z-10 overflow-hidden border-t border-border mt-16 pt-32 pb-16">
|
||||
<div className="mx-auto max-w-7xl px-6">
|
||||
<Reveal>
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-accent">
|
||||
<div className="mx-auto max-w-4xl text-center mb-16">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-4">
|
||||
Ecosystem
|
||||
</div>
|
||||
<h2 className="mt-6 text-4xl font-black tracking-tight md:text-5xl">One group, connected capability.</h2>
|
||||
<p className="mt-6 text-lg text-muted-foreground">A growing network designed to support enterprise from machinery to long-term operations.</p>
|
||||
</p>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase md:text-6xl">One group, connected capability.</h2>
|
||||
<p className="mt-8 text-sm font-medium uppercase tracking-widest text-muted-foreground">A growing network designed to support enterprise from machinery to long-term operations.</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
<div className="mt-16">
|
||||
@@ -240,31 +239,23 @@ function Index() {
|
||||
<TestimonialsMarquee testimonials={testimonials} />
|
||||
)}
|
||||
|
||||
<section className="relative z-10 border-t border-border/50 bg-gradient-to-b from-transparent to-mist/50">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32 text-center lg:py-40">
|
||||
<section className="relative z-10 bg-brand text-white overflow-hidden">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32 md:py-48 text-center">
|
||||
<Reveal>
|
||||
<div className="mx-auto max-w-4xl">
|
||||
<div className="inline-flex items-center gap-2 rounded-full bg-brand/10 px-4 py-1.5 text-xs font-bold uppercase tracking-widest text-brand">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-brand opacity-75"></span>
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-brand"></span>
|
||||
</span>
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-white/70 mb-8">
|
||||
Ready to scale
|
||||
</div>
|
||||
<h2 className="mt-8 text-4xl font-black tracking-tight text-foreground md:text-6xl md:leading-[1.1]">
|
||||
Need a machine spec'd for your output?
|
||||
</h2>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-xl leading-relaxed text-muted-foreground">
|
||||
Tell us your scale and target production — our Banke team responds with a tailored
|
||||
recommendation and pricing.
|
||||
</p>
|
||||
<div className="mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||
<Button asChild size="lg" className="h-14 w-full sm:w-auto rounded-full bg-brand px-10 text-base font-bold shadow-xl shadow-brand/20 transition-all hover:scale-105 hover:bg-brand/90">
|
||||
<Link to="/contact">Get a Quote</Link>
|
||||
</Button>
|
||||
<Button asChild size="lg" variant="ghost" className="h-14 w-full sm:w-auto rounded-full px-8 text-base font-bold transition-all hover:bg-muted">
|
||||
<Link to="/products">Browse Catalogue</Link>
|
||||
</Button>
|
||||
<h2 className="text-5xl font-display font-black tracking-tighter uppercase md:text-7xl lg:text-[7rem] leading-[0.9]">
|
||||
Need a machine<br />spec'd for your<br />output?
|
||||
</h2>
|
||||
<div className="mt-16 flex flex-col items-center justify-center gap-8 sm:flex-row">
|
||||
<Link to="/contact" className="inline-flex items-center gap-2 text-sm font-bold uppercase tracking-widest text-brand bg-white px-8 py-4 hover:bg-white/90 transition-colors">
|
||||
Get a Quote <ArrowRight className="h-4 w-4" />
|
||||
</Link>
|
||||
<Link to="/products" className="inline-flex items-center gap-2 text-sm font-bold uppercase tracking-widest text-white hover:text-white/70 transition-colors border-b border-white/30 pb-1 hover:border-white">
|
||||
Browse Catalogue
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
@@ -35,48 +35,45 @@ function Products() {
|
||||
/>
|
||||
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto max-w-7xl space-y-12 px-6 pb-24">
|
||||
{products?.map((product, i) => (
|
||||
<Reveal key={product.id} delay={i * 80}>
|
||||
<div className="group grid items-center gap-8 overflow-hidden rounded-3xl border border-border/50 bg-card p-6 shadow-lg transition-all hover:shadow-xl hover:shadow-brand/5 md:grid-cols-2 md:gap-12 md:p-10">
|
||||
{product.image && (
|
||||
<div className="overflow-hidden rounded-2xl shadow-md">
|
||||
<img
|
||||
src={product.image}
|
||||
loading="lazy"
|
||||
width={1024}
|
||||
height={768}
|
||||
alt={`${product.name} machinery`}
|
||||
className="aspect-[4/3] w-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<h2 className="text-3xl font-black tracking-tight text-foreground md:text-4xl">{product.name}</h2>
|
||||
{product.features && product.features.length > 0 && (
|
||||
<ul className="mt-8 grid gap-4 text-base text-muted-foreground sm:grid-cols-2">
|
||||
{product.features.map((feature) => (
|
||||
<li key={feature.id} className="flex items-center gap-3">
|
||||
<span className="flex h-6 w-6 items-center justify-center rounded-full bg-brand/10 text-brand">
|
||||
<svg className="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</span>
|
||||
<span className="font-medium">{feature.name}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32">
|
||||
<div className="flex flex-col gap-0 border-t border-border">
|
||||
{products?.map((product, i) => (
|
||||
<Reveal key={product.id} delay={i * 80}>
|
||||
<div className="group grid items-center gap-12 border-b border-border py-16 transition-colors hover:bg-muted/30 md:grid-cols-12">
|
||||
{product.image && (
|
||||
<div className="md:col-span-6 overflow-hidden bg-muted aspect-[4/3]">
|
||||
<img
|
||||
src={product.image}
|
||||
loading="lazy"
|
||||
alt={`${product.name} machinery`}
|
||||
className="w-full h-full object-cover grayscale transition duration-1000 group-hover:grayscale-0 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<Link
|
||||
to="/contact"
|
||||
className="mt-7 inline-block bg-ink px-6 py-3 text-sm font-semibold text-primary-foreground transition hover:bg-brand"
|
||||
>
|
||||
Request pricing
|
||||
</Link>
|
||||
<div className="md:col-span-6 md:pl-8">
|
||||
<span className="text-sm font-bold uppercase tracking-widest text-muted-foreground mb-4 block">0{i + 1}</span>
|
||||
<h2 className="text-4xl font-display font-black tracking-tighter uppercase text-foreground md:text-5xl">{product.name}</h2>
|
||||
{product.features && product.features.length > 0 && (
|
||||
<ul className="mt-8 grid gap-4 text-sm font-medium uppercase tracking-widest text-muted-foreground sm:grid-cols-2">
|
||||
{product.features.map((feature) => (
|
||||
<li key={feature.id} className="flex items-start gap-4">
|
||||
<span className="text-foreground">—</span>
|
||||
<span>{feature.name}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
<Link
|
||||
to="/contact"
|
||||
className="mt-12 inline-flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-background bg-foreground px-8 py-4 hover:bg-foreground/80 transition-colors"
|
||||
>
|
||||
Request pricing
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -80,31 +80,35 @@ function ProjectsEvents() {
|
||||
description="A look at recent work — machines delivered, lines commissioned and exhibitions attended."
|
||||
/>
|
||||
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto grid max-w-7xl gap-6 px-6 pb-24 md:grid-cols-3">
|
||||
{entries.map((e, i) => (
|
||||
<Reveal key={e.id} delay={i * 80}>
|
||||
<article className="group flex h-full flex-col overflow-hidden rounded-3xl border border-border/50 bg-card shadow-lg transition-all hover:-translate-y-1 hover:shadow-xl hover:shadow-brand/5">
|
||||
{e.image && (
|
||||
<img
|
||||
src={e.image}
|
||||
loading="lazy"
|
||||
width={1024}
|
||||
height={768}
|
||||
alt={e.title}
|
||||
className="aspect-[4/3] w-full object-cover transition-transform duration-700 group-hover:scale-105"
|
||||
/>
|
||||
)}
|
||||
<div className="p-6">
|
||||
<p className="inline-flex items-center gap-2 rounded-full bg-accent/10 px-3 py-1 text-xs font-bold uppercase tracking-widest text-accent">
|
||||
{e.year} · {e.tag}
|
||||
</p>
|
||||
<h2 className="mt-2 text-xl font-bold">{e.title}</h2>
|
||||
<p className="mt-2 text-sm text-muted-foreground">{e.copy}</p>
|
||||
</div>
|
||||
</article>
|
||||
</Reveal>
|
||||
))}
|
||||
<section className="relative z-10 border-t border-border mt-16">
|
||||
<div className="mx-auto max-w-7xl px-6 py-32">
|
||||
<div className="grid gap-16 md:grid-cols-2 lg:grid-cols-3">
|
||||
{entries.map((e, i) => (
|
||||
<Reveal key={e.id} delay={i * 80}>
|
||||
<article className="group flex h-full flex-col">
|
||||
{e.image && (
|
||||
<div className="aspect-[4/3] w-full overflow-hidden bg-muted mb-8">
|
||||
<img
|
||||
src={e.image}
|
||||
loading="lazy"
|
||||
alt={e.title}
|
||||
className="w-full h-full object-cover grayscale transition-transform duration-1000 group-hover:grayscale-0 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col flex-1 border-t-2 border-foreground pt-6">
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground">{e.year}</p>
|
||||
<span className="h-px flex-1 bg-border" />
|
||||
<p className="text-xs font-bold uppercase tracking-widest text-muted-foreground">{e.tag}</p>
|
||||
</div>
|
||||
<h2 className="text-2xl font-display font-black tracking-tight uppercase text-foreground">{e.title}</h2>
|
||||
<p className="mt-4 text-sm font-medium leading-relaxed text-muted-foreground">{e.copy}</p>
|
||||
</div>
|
||||
</article>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
+44
-58
@@ -34,68 +34,54 @@ function Team() {
|
||||
description="A compact, hands-on team of engineers, machinists and trade specialists working from Kohalpur-11, Banke."
|
||||
/>
|
||||
|
||||
<section className="relative z-10">
|
||||
<div className="mx-auto grid max-w-7xl gap-4 px-6 pb-24 md:grid-cols-2 lg:grid-cols-3">
|
||||
{people?.map((person, i) => (
|
||||
<Reveal key={person.id} delay={i * 70}>
|
||||
<div className="flex h-full flex-col justify-between rounded-xl border border-border bg-card p-6 shadow-sm transition-all hover:shadow-md">
|
||||
|
||||
{/* Top Section: Avatar, Name, Status */}
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
{person.image ? (
|
||||
<img src={person.image} alt={person.name} className="h-11 w-11 rounded-full object-cover" />
|
||||
) : (
|
||||
<div className="grid h-11 w-11 place-items-center rounded-full bg-muted font-display text-lg font-bold text-foreground">
|
||||
{String(person.name).charAt(0)}
|
||||
</div>
|
||||
)}
|
||||
<section className="relative z-10 border-t border-border">
|
||||
<div className="mx-auto max-w-7xl px-6 pb-32 pt-16">
|
||||
<div className="grid gap-16 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{people?.map((person, i) => (
|
||||
<Reveal key={person.id} delay={i * 70}>
|
||||
<div className="group flex h-full flex-col">
|
||||
{person.image ? (
|
||||
<div className="aspect-[3/4] w-full overflow-hidden bg-muted mb-6">
|
||||
<img src={person.image} alt={person.name} className="h-full w-full object-cover grayscale transition duration-700 group-hover:grayscale-0" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="aspect-[3/4] w-full bg-muted mb-6 grid place-items-center">
|
||||
<span className="font-display text-6xl font-black text-muted-foreground/30">{String(person.name).charAt(0)}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex-1 flex flex-col justify-between">
|
||||
<div>
|
||||
<h2 className="text-[15px] font-semibold text-foreground leading-tight">{person.name}</h2>
|
||||
<h3 className="text-[13px] text-muted-foreground mt-0.5">{person.position}</h3>
|
||||
<h2 className="text-2xl font-display font-black tracking-tight uppercase text-foreground">{person.name}</h2>
|
||||
<h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mt-2 mb-6 border-b border-border pb-4">{person.position}</h3>
|
||||
<p className="text-sm font-medium leading-relaxed text-foreground line-clamp-4">
|
||||
{person.short_intro || person.bio.replace(/<[^>]*>?/gm, '')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex flex-col gap-2">
|
||||
{person.email && (
|
||||
<a
|
||||
href={`mailto:${person.email}`}
|
||||
className="text-xs font-bold uppercase tracking-widest text-foreground hover:text-brand transition-colors flex items-center gap-2"
|
||||
>
|
||||
<Mail className="h-3 w-3" /> {person.email}
|
||||
</a>
|
||||
)}
|
||||
{person.phone_no && (
|
||||
<a
|
||||
href={`tel:${person.phone_no}`}
|
||||
className="text-xs font-bold uppercase tracking-widest text-foreground hover:text-brand transition-colors flex items-center gap-2"
|
||||
>
|
||||
<Phone className="h-3 w-3" /> {person.phone_no}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-[12px] text-muted-foreground">
|
||||
{person.email && "Open to chat"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Middle: Bio */}
|
||||
<p className="mt-5 text-[14px] leading-relaxed text-muted-foreground line-clamp-3">
|
||||
{person.short_intro || person.bio.replace(/<[^>]*>?/gm, '')}
|
||||
</p>
|
||||
|
||||
{/* Bottom: Location & Icons */}
|
||||
<div className="mt-6 flex items-center justify-between">
|
||||
<span className="text-[13px] text-muted-foreground">
|
||||
{person.phone_no ? person.phone_no : "Kohalpur, Nepal"}
|
||||
</span>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{person.email && (
|
||||
<a
|
||||
href={`mailto:${person.email}`}
|
||||
className="flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground transition hover:bg-muted hover:text-foreground"
|
||||
aria-label="Email"
|
||||
>
|
||||
<Mail className="h-4 w-4" />
|
||||
</a>
|
||||
)}
|
||||
{person.phone_no && (
|
||||
<a
|
||||
href={`tel:${person.phone_no}`}
|
||||
className="flex h-8 w-8 items-center justify-center rounded-md border border-border text-muted-foreground transition hover:bg-muted hover:text-foreground"
|
||||
aria-label="Phone"
|
||||
>
|
||||
<Phone className="h-4 w-4" />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
--color-brand: var(--brand);
|
||||
--color-ink: var(--ink);
|
||||
--color-mist: var(--mist);
|
||||
--font-display: "Archivo Black", sans-serif;
|
||||
--font-sans: "Hind", sans-serif;
|
||||
--font-display: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
||||
Reference in new issue
Block a user