diff --git a/src/app/layout/Footer.tsx b/src/app/layout/Footer.tsx index 7c9018b..bc5072e 100644 --- a/src/app/layout/Footer.tsx +++ b/src/app/layout/Footer.tsx @@ -89,7 +89,7 @@ export function Footer() { style={{ backgroundColor: 'var(--ink)', color: 'rgba(255,255,255,0.6)' }} > {/* TOP GRID */} -
+
- © ۱۴۰۳ اندیشکده فولاد ایران — تمام حقوق محفوظ است -
- {['حریم خصوصی', 'شرایط استفاده', 'درگاه پرداخت', 'نقشه سایت'].map(l => ( - - {l} - - ))} +
+ © ۱۴۰۳ اندیشکده فولاد ایران — تمام حقوق محفوظ است +
+ {['حریم خصوصی', 'شرایط استفاده', 'درگاه پرداخت', 'نقشه سایت'].map(l => ( + + {l} + + ))} +
diff --git a/src/app/layout/Header.tsx b/src/app/layout/Header.tsx index fc57a07..e1f5be4 100644 --- a/src/app/layout/Header.tsx +++ b/src/app/layout/Header.tsx @@ -5,13 +5,12 @@ import { Search, Menu, X } from 'lucide-react' import { motion, AnimatePresence } from 'framer-motion' /* ───────────────────────────────────────────────────────── - DESIGN TOKENS (mirrors CSS variables for inline styles) + DESIGN TOKENS ───────────────────────────────────────────────────────── */ const T = { paper: 'var(--paper)', paper2: 'var(--paper-2)', ink: 'var(--ink)', - ink2: 'var(--ink-2)', ink3: 'var(--ink-3)', ink4: 'var(--ink-4)', ink5: 'var(--ink-5)', @@ -29,67 +28,15 @@ const NAV_ITEMS = [ { label: 'رویدادها', to: '/events' }, { label: 'اسکنر جهانی', to: '/scanner' }, { label: 'تیم تحریریه', to: '/team' }, - { label: 'داشبورد بازار', to: '/market' }, { label: 'آرشیو', to: '/archive' }, ] -const COMPACT_NAV = [ - { label: 'گزارش‌ها', to: '/reports' }, - { label: 'بازار', to: '/market' }, - { label: 'رویدادها', to: '/events' }, - { label: 'ریسک', to: '/risks' }, -] - const META_LEFT = ['درباره ما', 'کارشناسان', 'همکاری', 'رسانه'] /* ───────────────────────────────────────────────────────── - HELPERS + NAV LINK (used in main + drawer) ───────────────────────────────────────────────────────── */ - -/** Social icon box */ -function SocialIcon({ label, href }: { label: string; href: string }) { - const [hovered, setHovered] = useState(false) - return ( - setHovered(true)} - onMouseLeave={() => setHovered(false)} - > - {label} - - ) -} - -/** Full nav link (expanded navbar) */ -function FullNavItem({ - to, - label, - isLast, -}: { - to: string - label: string - isLast: boolean -}) { +function MainNavItem({ to, label }: { to: string; label: string }) { const [hovered, setHovered] = useState(false) return ( setHovered(true)} onMouseLeave={() => setHovered(false)} style={({ isActive }: { isActive: boolean }): CSSProperties => ({ - padding: '12px 20px', - fontSize: 12, - fontWeight: 600, - color: isActive || hovered ? T.paper : T.ink, - background: isActive ? T.red : hovered ? T.ink : 'transparent', + fontSize: 13, + fontWeight: 600, + color: isActive ? T.red : hovered ? T.ink : T.ink3, textDecoration: 'none', - borderRight: !isLast ? `1px solid ${T.ruleThin}` : 'none', - display: 'flex', - alignItems: 'center', - transition: 'background 150ms, color 150ms', - whiteSpace: 'nowrap', - letterSpacing: '0.2px', + padding: '6px 0', + position: 'relative', + whiteSpace: 'nowrap', + transition: 'color 120ms', + borderBottom: isActive ? `2px solid ${T.red}` : '2px solid transparent', + letterSpacing: '0.1px', })} > {label} @@ -116,44 +61,6 @@ function FullNavItem({ ) } -/** Compact nav link */ -function CompactNavItem({ - to, - label, - isFirst, -}: { - to: string - label: string - isFirst: boolean -}) { - const [hovered, setHovered] = useState(false) - return ( - setHovered(true)} - onMouseLeave={() => setHovered(false)} - style={({ isActive }: { isActive: boolean }): CSSProperties => ({ - fontSize: 12, - fontWeight: 600, - color: isActive || hovered ? T.paper : T.ink, - background: isActive ? T.ink : hovered ? T.paper2 : 'transparent', - textDecoration: 'none', - padding: '0 14px', - height: 56, - display: 'flex', - alignItems: 'center', - borderRight: `1px solid ${T.ruleThin}`, - borderLeft: isFirst ? `1px solid ${T.ruleThin}` : 'none', - whiteSpace: 'nowrap', - transition: 'background 120ms, color 120ms', - })} - > - {label} - - ) -} - -/** Drawer nav link */ function DrawerNavItem({ to, label, @@ -171,15 +78,15 @@ function DrawerNavItem({ onMouseEnter={() => setHovered(true)} onMouseLeave={() => setHovered(false)} style={({ isActive }: { isActive: boolean }): CSSProperties => ({ - display: 'block', - padding: '13px 20px', - fontSize: 14, - fontWeight: 600, - color: isActive || hovered ? T.paper : T.ink, - background: isActive ? T.ink : hovered ? T.paper2 : 'transparent', + display: 'block', + padding: '13px 20px', + fontSize: 14, + fontWeight: 600, + color: isActive || hovered ? T.paper : T.ink, + background: isActive ? T.ink : hovered ? T.paper2 : 'transparent', textDecoration: 'none', - borderBottom: `1px solid ${T.ruleThin}`, - transition: 'background 120ms, color 120ms', + borderBottom: `1px solid ${T.ruleThin}`, + transition: 'background 120ms, color 120ms', })} > {label} @@ -191,21 +98,14 @@ function DrawerNavItem({ MAIN COMPONENT ───────────────────────────────────────────────────────── */ export default function Header() { - const [compact, setCompact] = useState(false) const [mobileOpen, setMobileOpen] = useState(false) const [isMobile, setIsMobile] = useState(false) - const searchRef = useRef(null) - - /* scroll listener */ - useEffect(() => { - const onScroll = () => setCompact(window.scrollY > 80) - window.addEventListener('scroll', onScroll, { passive: true }) - return () => window.removeEventListener('scroll', onScroll) - }, []) + const [searchOpen, setSearchOpen] = useState(false) + const searchInputRef = useRef(null) /* viewport listener */ useEffect(() => { - const mq = window.matchMedia('(max-width: 767px)') + const mq = window.matchMedia('(max-width: 1023px)') const handler = (e: MediaQueryListEvent | MediaQueryList) => setIsMobile(e.matches) handler(mq) mq.addEventListener('change', handler) @@ -218,379 +118,266 @@ export default function Header() { return () => { document.body.style.overflow = '' } }, [mobileOpen]) - const showCompact = compact || isMobile + /* focus search on open */ + useEffect(() => { + if (searchOpen) searchInputRef.current?.focus() + }, [searchOpen]) return (
- {/* ════════════════════════════════════════════ - EXPANDED STATE - ════════════════════════════════════════════ */} - - {!showCompact && ( - +
+ {/* Right: date */} + + شنبه ۲۱ بهمن ۱۴۰۳ · دوره دوازدهم + + + {/* Left: meta links + login */} + +
+
+ + {/* ═══════════════════════════════════════════ + MAIN BAR — brand | nav | actions + ═══════════════════════════════════════════ */} +
+
+ {/* ── Brand ── */} + - - {/* ── TOP META BAR ─────────────────────────── */} -
- {/* Right: login / language */} - - - {/* Center: date */} - - شنبه ۲۱ بهمن ۱۴۰۳ · دوره دوازدهم - - - {/* Left: secondary nav */} - -
- - {/* ── MASTHEAD MAIN ────────────────────────── */} -
+ - {/* Left col */} -
-
-

- تحلیل مستقل · سیاست‌گذاری -

-

- ۲۸۰ گزارش منتشرشده · ۴۵ متخصص -

-
-
- - - -
-
+ IRAN STEEL POLICY INSTITUTE +
+ - {/* Center col */} -
-

- اندیشکده فولاد ایران -

- -

- IRAN STEEL POLICY INSTITUTE -

-
- - {/* Right col */} -
-
- -
-
- اشتراک سازمانی - ورود -
-
-
- - {/* ── NAV BAR ──────────────────────────────── */} + {/* ── Center: Nav (desktop only) ── */} + {!isMobile && ( - - )} - + )} - {/* ════════════════════════════════════════════ - COMPACT STATE - ════════════════════════════════════════════ */} - - {showCompact && ( - -
+ {/* Search icon button */} + - {/* Desktop compact nav */} - {!isMobile ? ( - - ) : ( - /* Mobile hamburger */ - - )} + {/* Subscribe CTA — desktop only */} + {!isMobile && اشتراک} + + {/* Mobile menu */} + {isMobile && ( + + )} +
+
+
+ + {/* ═══════════════════════════════════════════ + SEARCH DROPDOWN + ═══════════════════════════════════════════ */} + + {searchOpen && ( + +
+ e.key === 'Escape' && setSearchOpen(false)} + style={{ + width: '100%', + border: `1px solid ${T.ink}`, + padding: '12px 16px', + fontSize: 14, + background: T.paper, + color: T.ink, + outline: 'none', + borderRadius: 0, + fontFamily: 'inherit', + direction: 'rtl', + }} + />
)}
- {/* ════════════════════════════════════════════ + {/* ═══════════════════════════════════════════ MOBILE DRAWER - ════════════════════════════════════════════ */} + ═══════════════════════════════════════════ */} {mobileOpen && ( <> - {/* Overlay */} setMobileOpen(false)} style={{ - position: 'fixed', - inset: 0, + position: 'fixed', + inset: 0, background: 'rgba(26,23,18,0.55)', - zIndex: 100, + zIndex: 100, }} /> - - {/* Drawer panel */} {/* Drawer header */}
- + اندیشکده فولاد ایران
- {/* Nav list */} + {/* Nav */}