From 8c5d2a973964cf229f60573081ee272ebee4d2b6 Mon Sep 17 00:00:00 2001 From: alireza Date: Mon, 25 May 2026 17:17:16 +0330 Subject: [PATCH] Refine homepage layout, typography, and component polish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Header: replaced 3-bar masthead with slim dark meta strip + 68px main bar (brand · centered nav · search/CTA actions). ~60% shorter than before. - Home: added numbered SectionLabel chapter markers (01–07) between sections with red accent bar; alternated paper/paper-2 backgrounds for clearer section separation. - Typography: wrapped base h1–h4 and p element styles in @layer base so Tailwind utilities (text-white, etc.) can override defaults. Previously unlayered p { color: var(--ink-3) } was overriding all carousel white titles, making them appear grey-brown. - Carousel: removed pagination arrows; strengthened title gradient, added top centered red category badge, text-shadow + generous padding so titles never crash into card edges. Modal hero received same treatment with overflow-safe inset positioning. - PlansSection: rewrote with compact shadcn-pricing pattern; price reduced from 42px to 26px; featured plan elevated with translateY and shadow; star badge for "Popular" plan. - TeamSection: redesigned member cards more compact (avatar 60→44px, reports count moved to top-end, line-clamp on bio). - Removed inline padding overrides across all sections so Tailwind max-md:px-5 mobile responsiveness actually works. --- src/app/layout/Footer.tsx | 46 +- src/app/layout/Header.tsx | 877 +++++++----------- src/components/ui/apple-cards-carousel.tsx | 87 +- src/index.css | 119 +-- src/pages/Archive/Archive.tsx | 26 +- src/pages/Home/Home.tsx | 113 ++- src/pages/Home/sections/EventsSection.tsx | 27 +- .../Home/sections/GlobalScannerSection.tsx | 200 ++-- src/pages/Home/sections/HeroSection.tsx | 440 +++++---- .../Home/sections/LatestNewsBentoSection.tsx | 25 +- src/pages/Home/sections/NewsletterSection.tsx | 4 +- src/pages/Home/sections/PlansSection.tsx | 369 ++++---- .../Home/sections/ReportsCarouselSection.tsx | 41 +- src/pages/Home/sections/RiskSection.tsx | 62 +- src/pages/Home/sections/SnapshotBar.tsx | 3 +- src/pages/Home/sections/TeamSection.tsx | 223 ++++- src/pages/Market/Market.tsx | 25 +- src/pages/Risks/Risks.tsx | 183 ++-- src/pages/Scanner/Scanner.tsx | 35 +- src/pages/Special/Special.tsx | 6 +- 20 files changed, 1406 insertions(+), 1505 deletions(-) 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 */}