fix: mobile-responsive nav with hamburger menu at 480px
This commit is contained in:
+139
-14
@@ -1,6 +1,7 @@
|
|||||||
// Top nav — minimal, sticky, blurred
|
// Top nav — minimal, sticky, blurred — mobile-responsive
|
||||||
const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
||||||
const [scrolled, setScrolled] = React.useState(false);
|
const [scrolled, setScrolled] = React.useState(false);
|
||||||
|
const [menuOpen, setMenuOpen] = React.useState(false);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const onScroll = () => setScrolled(window.scrollY > 12);
|
const onScroll = () => setScrolled(window.scrollY > 12);
|
||||||
@@ -17,6 +18,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<nav style={{
|
<nav style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
top: 0,
|
top: 0,
|
||||||
@@ -36,10 +38,10 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
height: 64,
|
height: 64,
|
||||||
}}>
|
}}>
|
||||||
{/* Brand */}
|
{/* Brand */}
|
||||||
<a href="#top" style={{ display: "flex", alignItems: "center", gap: 10 }}>
|
<a href="#top" style={{ display: "flex", alignItems: "center", gap: 10, flexShrink: 0 }}>
|
||||||
<Icons.Logo size={26} />
|
<Icons.Logo size={26} />
|
||||||
<span style={{ fontWeight: 600, fontSize: 15, letterSpacing: "-0.01em" }}>{PORTFOLIO_DATA.brand.name}</span>
|
<span style={{ fontWeight: 600, fontSize: 15, letterSpacing: "-0.01em" }}>{PORTFOLIO_DATA.brand.name}</span>
|
||||||
<span style={{
|
<span className="nav-badge" style={{
|
||||||
fontFamily: "var(--font-mono)",
|
fontFamily: "var(--font-mono)",
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
color: "var(--text-faint)",
|
color: "var(--text-faint)",
|
||||||
@@ -50,10 +52,10 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
}}>v.2026</span>
|
}}>v.2026</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{/* Center links */}
|
{/* Center links — hidden on mobile */}
|
||||||
<div style={{ display: "flex", gap: 4, alignItems: "center" }} className="nav-links">
|
<div style={{ display: "flex", gap: 4, alignItems: "center" }} className="nav-links">
|
||||||
{links.map(l => (
|
{links.map(l => (
|
||||||
<a key={l.id} href={`#${l.id}`} style={{
|
<a key={l.id} href={"#" + l.id} style={{
|
||||||
fontSize: 13.5,
|
fontSize: 13.5,
|
||||||
color: "var(--text-dim)",
|
color: "var(--text-dim)",
|
||||||
padding: "6px 12px",
|
padding: "6px 12px",
|
||||||
@@ -66,9 +68,9 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right: ⌘K, theme, hire */}
|
{/* Right — desktop */}
|
||||||
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
<div className="nav-right" style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
||||||
<button onClick={onCmdK} style={{
|
<button onClick={onCmdK} className="nav-search-btn" style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: 8,
|
gap: 8,
|
||||||
@@ -102,8 +104,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
{theme === "dark" ? <Icons.Sun size={15} /> : <Icons.Moon size={15} />}
|
{theme === "dark" ? <Icons.Sun size={15} /> : <Icons.Moon size={15} />}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* EN/BN toggle */}
|
<button onClick={onToggleLang} className="nav-lang-btn" style={{
|
||||||
<button onClick={onToggleLang} style={{
|
|
||||||
padding: "6px 10px",
|
padding: "6px 10px",
|
||||||
background: "transparent",
|
background: "transparent",
|
||||||
border: "1px solid var(--line)",
|
border: "1px solid var(--line)",
|
||||||
@@ -117,8 +118,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
{lang === "en" ? "বাং" : "EN"}
|
{lang === "en" ? "বাং" : "EN"}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Get a Quote */}
|
<a href="mailto:hello@auraajenticai.cloud?subject=Project Quote" className="nav-quote-btn" style={{
|
||||||
<a href="mailto:hello@auraajenticai.cloud?subject=Project Quote" style={{
|
|
||||||
padding: "7px 13px",
|
padding: "7px 13px",
|
||||||
background: "transparent",
|
background: "transparent",
|
||||||
border: "1px solid var(--line)",
|
border: "1px solid var(--line)",
|
||||||
@@ -132,8 +132,7 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
Get a Quote
|
Get a Quote
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{/* Client Login */}
|
<a href="https://auth.auraajenticai.cloud/login" className="nav-login-btn" style={{
|
||||||
<a href="https://auth.auraajenticai.cloud/login" style={{
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: 6,
|
gap: 6,
|
||||||
@@ -149,14 +148,140 @@ const Nav = ({ onCmdK, theme, onToggleTheme, accent, lang, onToggleLang }) => {
|
|||||||
Client Login <Icons.Arrow size={13} />
|
Client Login <Icons.Arrow size={13} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Hamburger — mobile only */}
|
||||||
|
<button
|
||||||
|
className="nav-hamburger"
|
||||||
|
onClick={() => setMenuOpen(o => !o)}
|
||||||
|
aria-label={menuOpen ? "Close menu" : "Open menu"}
|
||||||
|
style={{
|
||||||
|
display: "none",
|
||||||
|
width: 36, height: 36,
|
||||||
|
background: "transparent",
|
||||||
|
border: "1px solid var(--line)",
|
||||||
|
borderRadius: 8,
|
||||||
|
color: "var(--text-dim)",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexShrink: 0,
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{menuOpen ? (
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||||
|
<path d="M2 2l12 12M14 2L2 14" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||||
|
<path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>{`
|
<style>{`
|
||||||
@media (max-width: 880px) {
|
@media (max-width: 880px) {
|
||||||
.nav-links { display: none !important; }
|
.nav-links { display: none !important; }
|
||||||
}
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.nav-search-btn { display: none !important; }
|
||||||
|
.nav-quote-btn { display: none !important; }
|
||||||
|
.nav-badge { display: none !important; }
|
||||||
|
.nav-lang-btn { display: none !important; }
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.nav-login-btn { display: none !important; }
|
||||||
|
.nav-hamburger { display: flex !important; }
|
||||||
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
{/* Mobile drawer */}
|
||||||
|
{menuOpen && (
|
||||||
|
<div style={{
|
||||||
|
position: "fixed",
|
||||||
|
top: 64,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
zIndex: 49,
|
||||||
|
background: "color-mix(in srgb, var(--bg) 96%, transparent)",
|
||||||
|
backdropFilter: "blur(20px)",
|
||||||
|
WebkitBackdropFilter: "blur(20px)",
|
||||||
|
borderBottom: "1px solid var(--line)",
|
||||||
|
padding: "1rem 20px 1.5rem",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
gap: 2,
|
||||||
|
}}>
|
||||||
|
{links.map(l => (
|
||||||
|
<a
|
||||||
|
key={l.id}
|
||||||
|
href={"#" + l.id}
|
||||||
|
onClick={() => setMenuOpen(false)}
|
||||||
|
style={{
|
||||||
|
fontSize: 15,
|
||||||
|
color: "var(--text-dim)",
|
||||||
|
padding: "12px 4px",
|
||||||
|
textDecoration: "none",
|
||||||
|
display: "block",
|
||||||
|
borderBottom: "1px solid var(--line)",
|
||||||
|
}}
|
||||||
|
>{l.label}</a>
|
||||||
|
))}
|
||||||
|
<div style={{ display: "flex", gap: 8, marginTop: 14, flexWrap: "wrap" }}>
|
||||||
|
<button onClick={() => { onToggleTheme(); setMenuOpen(false); }} style={{
|
||||||
|
padding: "8px 14px",
|
||||||
|
background: "transparent",
|
||||||
|
border: "1px solid var(--line)",
|
||||||
|
borderRadius: 8,
|
||||||
|
color: "var(--text-dim)",
|
||||||
|
fontSize: 13,
|
||||||
|
cursor: "pointer",
|
||||||
|
}}>
|
||||||
|
{theme === "dark" ? "Light" : "Dark"}
|
||||||
|
</button>
|
||||||
|
<button onClick={() => { onToggleLang(); setMenuOpen(false); }} style={{
|
||||||
|
padding: "8px 14px",
|
||||||
|
background: "transparent",
|
||||||
|
border: "1px solid var(--line)",
|
||||||
|
borderRadius: 8,
|
||||||
|
color: "var(--text-dim)",
|
||||||
|
fontSize: 13,
|
||||||
|
cursor: "pointer",
|
||||||
|
fontWeight: 600,
|
||||||
|
}}>
|
||||||
|
{lang === "en" ? "বাংলা" : "English"}
|
||||||
|
</button>
|
||||||
|
<a
|
||||||
|
href="mailto:hello@auraajenticai.cloud?subject=Project Quote"
|
||||||
|
onClick={() => setMenuOpen(false)}
|
||||||
|
style={{
|
||||||
|
padding: "8px 14px",
|
||||||
|
background: "transparent",
|
||||||
|
border: "1px solid var(--line)",
|
||||||
|
borderRadius: 8,
|
||||||
|
color: "var(--text-dim)",
|
||||||
|
fontSize: 13,
|
||||||
|
textDecoration: "none",
|
||||||
|
}}
|
||||||
|
>Get a Quote</a>
|
||||||
|
<a
|
||||||
|
href="https://auth.auraajenticai.cloud/login"
|
||||||
|
onClick={() => setMenuOpen(false)}
|
||||||
|
style={{
|
||||||
|
padding: "8px 14px",
|
||||||
|
background: "var(--text)",
|
||||||
|
color: "var(--bg)",
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: 500,
|
||||||
|
borderRadius: 8,
|
||||||
|
textDecoration: "none",
|
||||||
|
}}
|
||||||
|
>Client Login</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user