Brighten palette, rename to Andishkade Foolad Ayandeh, fix risk ticker loop

- Shift design tokens from warm beige/brown to cool off-white + slate inks
  with vivid corporate red/amber/green accents
- Rename brand from "اندیشکده فولاد ایران" / "Iran Steel Policy Institute"
  to "اندیشکده فولاد آینده" / "Future Steel Policy Institute"
- Replace JS-clone seamless-loop in RiskSection with JSX-doubled items,
  immune to StrictMode double-invocation that was leaving the ticker blank

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zaza 2026-05-26 18:39:17 +03:30
parent 848f03374e
commit 070de3ac1e
10 changed files with 32 additions and 45 deletions

View File

@ -4,13 +4,13 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="اندیشکده فولاد ایران — مرکز مستقل تحلیل راهبردی و سیاست‌گذاری صنعت فولاد" /> <meta name="description" content="اندیشکده فولاد آینده — مرکز مستقل تحلیل راهبردی و سیاست‌گذاری صنعت فولاد" />
<!-- Vazir font preloads (critical weights) --> <!-- Vazir font preloads (critical weights) -->
<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

@ -106,7 +106,7 @@ export function Footer() {
lineHeight: 1.2, marginBottom: 4, lineHeight: 1.2, marginBottom: 4,
}} }}
> >
اندیشکده فولاد ایران اندیشکده فولاد آینده
</div> </div>
<div <div
style={{ style={{
@ -115,7 +115,7 @@ export function Footer() {
marginBottom: 20, direction: 'ltr', textAlign: 'right', marginBottom: 20, direction: 'ltr', textAlign: 'right',
}} }}
> >
IRAN STEEL POLICY INSTITUTE FUTURE STEEL POLICY INSTITUTE
</div> </div>
<p style={{ fontSize: 13, lineHeight: 1.75, color: 'rgba(255,255,255,0.5)', marginBottom: 20, maxWidth: 300 }}> <p style={{ fontSize: 13, lineHeight: 1.75, color: 'rgba(255,255,255,0.5)', marginBottom: 20, maxWidth: 300 }}>
مرکز مستقل تحلیل راهبردی و سیاستگذاری صنعت فولاد و فلزات کشور مرکز مستقل تحلیل راهبردی و سیاستگذاری صنعت فولاد و فلزات کشور
@ -183,7 +183,7 @@ export function Footer() {
}} }}
className="max-w-7xl mx-auto w-full px-12 max-md:px-5" className="max-w-7xl mx-auto w-full px-12 max-md:px-5"
> >
<span>© ۱۴۰۳ اندیشکده فولاد ایران تمام حقوق محفوظ است</span> <span>© ۱۴۰۳ اندیشکده فولاد آینده تمام حقوق محفوظ است</span>
<div style={{ display: 'flex', gap: 18 }}> <div style={{ display: 'flex', gap: 18 }}>
{['حریم خصوصی', 'شرایط استفاده', 'درگاه پرداخت', 'نقشه سایت'].map(l => ( {['حریم خصوصی', 'شرایط استفاده', 'درگاه پرداخت', 'نقشه سایت'].map(l => (
<a <a

View File

@ -260,7 +260,7 @@ export default function Header() {
}} }}
className="max-md:text-[16px]" className="max-md:text-[16px]"
> >
اندیشکده فولاد ایران اندیشکده فولاد آینده
</span> </span>
<span <span
style={{ style={{
@ -273,7 +273,7 @@ export default function Header() {
}} }}
className="max-md:hidden" className="max-md:hidden"
> >
IRAN STEEL POLICY INSTITUTE FUTURE STEEL POLICY INSTITUTE
</span> </span>
</NavLink> </NavLink>
@ -442,7 +442,7 @@ export default function Header() {
}} }}
> >
<span style={{ fontSize: 14, fontWeight: 800 }}> <span style={{ fontSize: 14, fontWeight: 800 }}>
اندیشکده فولاد ایران اندیشکده فولاد آینده
</span> </span>
<button <button
aria-label="بستن منو" aria-label="بستن منو"

View File

@ -43,20 +43,20 @@
DESIGN TOKENS DESIGN TOKENS
*/ */
:root { :root {
--paper: #f4efe7; --paper: #fafbfd;
--paper-2: #ede8de; --paper-2: #f1f4f9;
--paper-3: #e4ddd0; --paper-3: #e4eaf2;
--ink: #1a1712; --ink: #0f172a;
--ink-2: #2e2a25; --ink-2: #1e293b;
--ink-3: #4a4540; --ink-3: #334155;
--ink-4: #6b6560; --ink-4: #64748b;
--ink-5: #766e68; --ink-5: #94a3b8;
--ink-6: #c8c2bc; --ink-6: #cbd5e1;
--rule-thin: rgba(26,23,18,0.12); --rule-thin: rgba(15,23,42,0.10);
--red: #9b1c1c; --red: #dc2626;
--red-2: #b52020; --red-2: #ef4444;
--amber: #92400e; --amber: #d97706;
--green-ink: #166534; --green-ink: #059669;
} }
/* /*

View File

@ -198,7 +198,7 @@ export default function LatestNewsBentoSection() {
<div style={{ width: 28, height: 28, background: 'var(--red)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: 11, fontWeight: 900, flexShrink: 0 }}>م</div> <div style={{ width: 28, height: 28, background: 'var(--red)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: 11, fontWeight: 900, flexShrink: 0 }}>م</div>
<div> <div>
<div style={{ fontSize: 12, fontWeight: 700, color: 'var(--ink)' }}>دکتر علی محمدی</div> <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--ink)' }}>دکتر علی محمدی</div>
<div style={{ fontSize: 10, color: 'var(--ink-5)' }}>مدیر ارشد پژوهش · اندیشکده فولاد</div> <div style={{ fontSize: 10, color: 'var(--ink-5)' }}>مدیر ارشد پژوهش · اندیشکده فولاد آینده</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,4 +1,3 @@
import { useEffect, useRef, useState } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
/* ─── Risk data ──────────────────────────────────────────── */ /* ─── Risk data ──────────────────────────────────────────── */
@ -75,19 +74,9 @@ const LEVEL = {
/* ─── Section ────────────────────────────────────────────── */ /* ─── Section ────────────────────────────────────────────── */
export default function RiskSection() { export default function RiskSection() {
const containerRef = useRef<HTMLDivElement>(null) /* Duplicate items for seamless infinite loop (handled in JSX, not effect, to
const listRef = useRef<HTMLUListElement>(null) stay immune to StrictMode double-invocation that would otherwise clone twice). */
const [ready, setReady] = useState(false) const loopItems = [...riskItems, ...riskItems]
useEffect(() => {
if (!containerRef.current || !listRef.current) return
/* Clone all items for seamless loop */
const original = Array.from(listRef.current.children)
original.forEach(item => {
listRef.current!.appendChild(item.cloneNode(true))
})
setReady(true)
}, [])
return ( return (
<section style={{ background: 'var(--paper)' }}> <section style={{ background: 'var(--paper)' }}>
@ -144,7 +133,6 @@ export default function RiskSection() {
{/* ── Auto-scroll ticker ── */} {/* ── Auto-scroll ticker ── */}
<div <div
ref={containerRef}
style={{ style={{
position: 'relative', position: 'relative',
overflow: 'hidden', overflow: 'hidden',
@ -157,8 +145,7 @@ export default function RiskSection() {
}} }}
> >
<ul <ul
ref={listRef} className="animate-scroll-risk"
className={ready ? 'animate-scroll-risk' : ''}
style={{ style={{
display: 'flex', display: 'flex',
gap: 20, gap: 20,
@ -172,7 +159,7 @@ export default function RiskSection() {
onMouseEnter={e => (e.currentTarget.style.animationPlayState = 'paused')} onMouseEnter={e => (e.currentTarget.style.animationPlayState = 'paused')}
onMouseLeave={e => (e.currentTarget.style.animationPlayState = 'running')} onMouseLeave={e => (e.currentTarget.style.animationPlayState = 'running')}
> >
{riskItems.map((item, idx) => { {loopItems.map((item, idx) => {
const cfg = LEVEL[item.level] const cfg = LEVEL[item.level]
return ( return (
<li <li

View File

@ -55,7 +55,7 @@ export default function Risks() {
marginBottom: '12px', marginBottom: '12px',
}} }}
> >
اندیشکده فولاد ایران پایش ریسک اندیشکده فولاد آینده پایش ریسک
</div> </div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: '16px' }}> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', flexWrap: 'wrap', gap: '16px' }}>
<h1 <h1

View File

@ -167,7 +167,7 @@ export default function Scanner() {
marginBottom: '12px', marginBottom: '12px',
}} }}
> >
اندیشکده فولاد ایران دادههای بازار اندیشکده فولاد آینده دادههای بازار
</div> </div>
<div <div
style={{ style={{

View File

@ -261,7 +261,7 @@ export default function Special() {
fontWeight: 600, fontWeight: 600,
}} }}
> >
اندیشکده فولاد ایران پژوهشهای تخصصی اندیشکده فولاد آینده پژوهشهای تخصصی
</div> </div>
<h1 <h1
style={{ style={{

View File

@ -587,7 +587,7 @@ export default function Subscribe() {
marginBottom: 16, marginBottom: 16,
}} }}
> >
اندیشکده فولاد ایران اندیشکده فولاد آینده
</p> </p>
<h2 <h2
style={{ style={{