Home polish: brand copy, footer, section reorg, smaller reports, split casts

- Tab title -> "اندیشکده فولاد آینده"; header/footer subtitle -> The Steel Futures Institute
- Footer: brand description, social links (LinkedIn/Twitter/Aparat/Telegram), drop nav links
- Remove de-zoom HeroSection; SpreadFeatures is now the hero
- Comment out InternalNewsSection + RiskSection (restorable)
- Move IntegrationsSection under RadarTechSection
- FactoryReportsScroll: compact 4-up row instead of large masonry
- Split Videocast and Podcast into separate full-width sections (only prop)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
This commit is contained in:
alireza 2026-06-10 11:47:30 +03:30
parent 74a8bf567e
commit 27e64ee3e6
6 changed files with 66 additions and 75 deletions

View File

@ -10,7 +10,7 @@
<link rel="preload" href="/fonts/Vazir-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/Vazir-Regular.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/Vazir-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/Vazir-Bold.woff2" as="font" type="font/woff2" crossorigin />
<title>اندیشکده فولاد آینده — تحلیل راهبردی صنعت فولاد</title> <title>اندیشکده فولاد آینده</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -1,47 +1,30 @@
import { useState } from 'react' import { useState } from 'react'
function SocialIcon({ label }: { label: string }) { function SocialIcon({ label, name, href }: { label: string; name: string; href: string }) {
const [hovered, setHovered] = useState(false) const [hovered, setHovered] = useState(false)
return ( return (
<div <a
role="button" tabIndex={0} aria-label={label} href={href} target="_blank" rel="noopener noreferrer" aria-label={name} title={name}
onMouseEnter={() => setHovered(true)} onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)} onMouseLeave={() => setHovered(false)}
style={{ style={{
width: 32, height: 32, width: 36, height: 36, borderRadius: 8,
border: `1px solid ${hovered ? 'rgba(255,255,255,0.4)' : 'rgba(255,255,255,0.15)'}`, border: `1px solid ${hovered ? 'rgba(255,255,255,0.4)' : 'rgba(255,255,255,0.15)'}`,
background: hovered ? 'rgba(255,255,255,0.08)' : 'transparent',
display: 'flex', alignItems: 'center', justifyContent: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: 11, fontWeight: 700, fontSize: 11, fontWeight: 700, textDecoration: 'none',
color: hovered ? '#fff' : 'rgba(255,255,255,0.45)', color: hovered ? '#fff' : 'rgba(255,255,255,0.5)',
cursor: 'pointer', transition: 'border-color 150ms, color 150ms', flexShrink: 0, cursor: 'pointer', transition: 'all 150ms', flexShrink: 0,
}}
>{label}</div>
)
}
function FooterLink({ href, label }: { href: string; label: string }) {
const [hovered, setHovered] = useState(false)
return (
<a href={href}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
style={{
fontSize: 14,
color: hovered ? '#fff' : 'rgba(255,255,255,0.6)',
textDecoration: 'none',
cursor: 'pointer',
transition: 'color 150ms',
display: 'block',
padding: '4px 0',
}} }}
>{label}</a> >{label}</a>
) )
} }
const FOOTER_LINKS = [ const SOCIALS = [
{ label: 'درباره ما', href: '#' }, { label: 'in', name: 'لینکدین', href: '#' },
{ label: 'همکاری با ما', href: '#' }, { label: 'X', name: 'توییتر', href: '#' },
{ label: 'تماس با ما', href: '#' }, { label: 'آپ', name: 'آپارات', href: '#' },
{ label: 'tg', name: 'تلگرام', href: '#' },
] ]
function NewsletterBox() { function NewsletterBox() {
@ -96,35 +79,35 @@ export function Footer() {
{/* Brand */} {/* Brand */}
<div> <div>
<div style={{ fontSize: 24, fontWeight: 900, color: '#fff', lineHeight: 1.3, marginBottom: 8 }}> <div style={{ fontSize: 24, fontWeight: 900, color: '#fff', lineHeight: 1.3, marginBottom: 6 }}>
اندیشکده فولاد آینده اندیشکده فولاد آینده
</div> </div>
<div style={{ <div style={{
fontSize: 10, letterSpacing: 2, fontSize: 10, letterSpacing: 2,
color: 'rgba(255,255,255,0.3)', color: 'rgba(255,255,255,0.3)',
textTransform: 'uppercase', textTransform: 'uppercase',
marginBottom: 24, marginBottom: 18,
lineHeight: 1.6, lineHeight: 1.6,
}}> }}>
FUTURE STEEL POLICY INSTITUTE The Steel Futures Institute
</div> </div>
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}> <p style={{
<SocialIcon label="in" /> fontSize: 14, lineHeight: 2, color: 'rgba(255,255,255,0.6)',
<SocialIcon label="tg" /> maxWidth: 460, margin: '0 0 26px',
<SocialIcon label="tw" /> }}>
<SocialIcon label="@" /> فضایی همدلانه برای اندیشیدن به فردای صنعت؛ جایی که دانش، آیندهپژوهی و نوآوری به بینشهایی برای توسعه صنعتی تبدیل میشوند.
</p>
<div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
{SOCIALS.map(s => (
<SocialIcon key={s.name} label={s.label} name={s.name} href={s.href} />
))}
</div> </div>
</div> </div>
{/* Links + newsletter */} {/* Newsletter */}
<nav aria-label="پیوندهای پایین" style={{ display: 'flex', flexDirection: 'column', gap: 4 }}> <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' }}>
{FOOTER_LINKS.map(link => (
<FooterLink key={link.label} href={link.href} label={link.label} />
))}
<div style={{ marginTop: 16 }}>
<NewsletterBox /> <NewsletterBox />
</div> </div>
</nav>
</div> </div>
</div> </div>

View File

@ -230,7 +230,7 @@ export default function Header() {
</span> </span>
<span style={{ fontSize: 8, letterSpacing: '2.5px', color: T.ink5, fontWeight: 600, textTransform: 'uppercase', whiteSpace: 'nowrap' }} <span style={{ fontSize: 8, letterSpacing: '2.5px', color: T.ink5, fontWeight: 600, textTransform: 'uppercase', whiteSpace: 'nowrap' }}
className="max-md:hidden"> className="max-md:hidden">
FUTURE STEEL POLICY INSTITUTE The Steel Futures Institute
</span> </span>
</div> </div>
</NavLink> </NavLink>

View File

@ -1,13 +1,12 @@
import HeroSection from './sections/HeroSection'
import SpreadFeatures from './sections/SpreadFeatures' import SpreadFeatures from './sections/SpreadFeatures'
import IntegrationsSection from './sections/IntegrationsSection' import IntegrationsSection from './sections/IntegrationsSection'
import InternalNewsSection from './sections/InternalNewsSection' // import InternalNewsSection from './sections/InternalNewsSection' // «تازه‌ترین اخبار صنعت» — disabled, restore anytime
import RadarTechSection from './sections/RadarTechSection' import RadarTechSection from './sections/RadarTechSection'
import MapEventsSection from './sections/MapEventsSection' import MapEventsSection from './sections/MapEventsSection'
import FactoryReportsScroll from './sections/FactoryReportsScroll' import FactoryReportsScroll from './sections/FactoryReportsScroll'
import NewsletterMarquee from './sections/NewsletterMarquee' import NewsletterMarquee from './sections/NewsletterMarquee'
import VideocastPodcastSection from './sections/VideocastPodcastSection' import VideocastPodcastSection from './sections/VideocastPodcastSection'
import RiskSection from './sections/RiskSection' // import RiskSection from './sections/RiskSection' // «نقشه ریسک صنعت» — disabled, restore anytime
import { useLang } from '@/context/LangContext' import { useLang } from '@/context/LangContext'
/* ─── Home page ──────────────────────────────────────── */ /* ─── Home page ──────────────────────────────────────── */
@ -15,16 +14,16 @@ export default function Home() {
const { lang } = useLang() const { lang } = useLang()
return ( return (
<div dir={lang === 'fa' ? 'rtl' : 'ltr'}> <div dir={lang === 'fa' ? 'rtl' : 'ltr'}>
<HeroSection />
<SpreadFeatures /> <SpreadFeatures />
<InternalNewsSection /> {/* <InternalNewsSection /> «تازه‌ترین اخبار صنعت» — disabled, restore anytime */}
<RadarTechSection /> <RadarTechSection />
<IntegrationsSection />
<MapEventsSection /> <MapEventsSection />
<NewsletterMarquee /> <NewsletterMarquee />
<FactoryReportsScroll /> <FactoryReportsScroll />
<IntegrationsSection /> <VideocastPodcastSection only="video" />
<VideocastPodcastSection /> <VideocastPodcastSection only="pod" />
<RiskSection /> {/* <RiskSection /> «نقشه ریسک صنعت» — disabled, restore anytime */}
</div> </div>
) )
} }

View File

@ -63,27 +63,27 @@ function ReportCard({ r, lang }: { r: FactoryReport; lang: 'fa' | 'en' }) {
export default function FactoryReportsScroll() { export default function FactoryReportsScroll() {
const { lang } = useLang() const { lang } = useLang()
const m = FACTORY_REPORTS_META[lang] const m = FACTORY_REPORTS_META[lang]
const reports = FACTORY_REPORTS.slice(0, 4) // compact: just the latest 4
return ( return (
<section style={{ background: '#faf7f4', padding: '90px 0' }} dir={lang === 'fa' ? 'rtl' : 'ltr'}> <section style={{ background: '#faf7f4', padding: '48px 0' }} dir={lang === 'fa' ? 'rtl' : 'ltr'}>
<div className="max-w-7xl mx-auto px-12 max-md:px-5"> <div className="max-w-7xl mx-auto px-12 max-md:px-5">
{/* heading */} {/* compact heading row — title on the start side, "view all" on the end */}
<motion.div <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 12, marginBottom: 24, flexWrap: 'wrap' }}>
initial={{ opacity: 0, y: 24 }} <div>
whileInView={{ opacity: 1, y: 0 }} <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '3px', color: GOLD, marginBottom: 6 }}>{m.overline}</div>
viewport={{ once: true, amount: 0.5 }} <h2 style={{ fontSize: 'clamp(20px, 2vw, 28px)', fontWeight: 900, color: NAVY, letterSpacing: '-0.5px', margin: 0 }}>{m.heading}</h2>
transition={{ duration: 0.6, ease: EASE }} </div>
style={{ textAlign: 'center', marginBottom: 56 }} <a href="#" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, fontWeight: 800, color: GOLD, textDecoration: 'none', whiteSpace: 'nowrap' }}>
> {m.cta}
<div style={{ fontSize: 11, fontWeight: 700, letterSpacing: '3px', color: GOLD, marginBottom: 12 }}>{m.overline}</div> <ArrowLeft size={14} style={{ transform: lang === 'fa' ? 'none' : 'rotate(180deg)' }} />
<h2 style={{ fontSize: 'clamp(28px, 3.4vw, 46px)', fontWeight: 900, color: NAVY, letterSpacing: '-1px', margin: '0 0 14px' }}>{m.heading}</h2> </a>
<p style={{ fontSize: 'clamp(14px, 1.2vw, 16px)', color: 'rgba(7,29,73,0.6)', lineHeight: 1.8, maxWidth: 520, margin: '0 auto' }}>{m.sub}</p> </div>
</motion.div>
{/* 3-column masonry; cards slide in from left / up / right */} {/* compact 4-up row */}
<div style={{ columnCount: 3, columnGap: 18 }} className="max-lg:![column-count:2] max-sm:![column-count:1]"> <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }} className="max-lg:!grid-cols-2 max-sm:!grid-cols-1">
{FACTORY_REPORTS.map((r) => ( {reports.map((r) => (
<ScrollAnimation key={r.id} direction={r.dir}> <ScrollAnimation key={r.id} direction={r.dir}>
<ReportCard r={r} lang={lang} /> <ReportCard r={r} lang={lang} />
</ScrollAnimation> </ScrollAnimation>

View File

@ -62,19 +62,25 @@ const T = {
}, },
} }
export default function VideocastPodcastSection() { export default function VideocastPodcastSection({ only }: { only?: 'video' | 'pod' }) {
const { lang } = useLang() const { lang } = useLang()
const t = T[lang] const t = T[lang]
const [activeVideo, setActiveVideo] = useState(0) const [activeVideo, setActiveVideo] = useState(0)
const [activePod, setActivePod] = useState(0) const [activePod, setActivePod] = useState(0)
const pod = PODCASTS[activePod] const pod = PODCASTS[activePod]
const showVideo = only !== 'pod'
const showPod = only !== 'video'
// when split into one column, give it full width instead of 60/40
const gridCols = only ? '1fr' : '60% 40%'
return ( return (
<section style={{ direction: lang === 'fa' ? 'rtl' : 'ltr', background: 'var(--paper)' }}> <section style={{ direction: lang === 'fa' ? 'rtl' : 'ltr', background: 'var(--paper)' }}>
<div className="max-w-7xl mx-auto px-12 max-md:px-5"> <div className="max-w-7xl mx-auto px-12 max-md:px-5">
<div style={{ display: 'grid', gridTemplateColumns: '60% 40%' }} className="max-lg:!grid-cols-1"> <div style={{ display: 'grid', gridTemplateColumns: gridCols }} className="max-lg:!grid-cols-1">
{/* ── VIDEOCAST 70% ── */} {/* ── VIDEOCAST 70% ── */}
{showVideo && (
<div style={{ padding: '48px 0 80px 40px', display: 'flex', flexDirection: 'column' }} className="max-md:!p-5"> <div style={{ padding: '48px 0 80px 40px', display: 'flex', flexDirection: 'column' }} className="max-md:!p-5">
{/* heading */} {/* heading */}
@ -139,8 +145,10 @@ export default function VideocastPodcastSection() {
))} ))}
</div> </div>
</div> </div>
)}
{/* ── PODCAST 30% ── */} {/* ── PODCAST 30% ── */}
{showPod && (
<div style={{ padding: '48px 40px 80px 0', background: 'var(--paper)', display: 'flex', flexDirection: 'column', borderRight: 'none' }} className="max-md:!p-5 max-lg:!border-r-0 max-lg:!border-t-2 max-lg:!border-t-[var(--ink)] max-lg:!pt-10"> <div style={{ padding: '48px 40px 80px 0', background: 'var(--paper)', display: 'flex', flexDirection: 'column', borderRight: 'none' }} className="max-md:!p-5 max-lg:!border-r-0 max-lg:!border-t-2 max-lg:!border-t-[var(--ink)] max-lg:!pt-10">
{/* heading */} {/* heading */}
@ -215,6 +223,7 @@ export default function VideocastPodcastSection() {
{t.listenAll} {t.listenAll}
</button> </button>
</div> </div>
)}
</div> </div>
</div> </div>