steelforesight/src/index.css

291 lines
10 KiB
CSS

@import "tailwindcss";
/* ═══════════════════════════════════════════════
VAZIR FONT FACES
═══════════════════════════════════════════════ */
@font-face {
font-family: 'Vazir';
src: url('/fonts/Vazir-Light.woff2') format('woff2');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Vazir';
src: url('/fonts/Vazir-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Vazir';
src: url('/fonts/Vazir-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Vazir';
src: url('/fonts/Vazir-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Vazir';
src: url('/fonts/Vazir-Black.woff2') format('woff2');
font-weight: 900;
font-style: normal;
font-display: swap;
}
/* ═══════════════════════════════════════════════
DESIGN TOKENS
═══════════════════════════════════════════════ */
:root {
--paper: #fafbfd;
--paper-2: #f1f4f9;
--paper-3: #e4eaf2;
--ink: #0f172a;
--ink-2: #1e293b;
--ink-3: #334155;
--ink-4: #64748b;
--ink-5: #94a3b8;
--ink-6: #cbd5e1;
--rule-thin: rgba(15,23,42,0.10);
--red: #dc2626;
--red-2: #ef4444;
--amber: #d97706;
--green-ink: #059669;
}
/* ═══════════════════════════════════════════════
TYPOGRAPHY SYSTEM
Scale (clamp: mobile → desktop)
--fs-display hero headlines 32 → 72px
--fs-h1 page-level headings 26 → 52px
--fs-h2 section headings 20 → 38px
--fs-h3 card/sub headings 15 → 22px
--fs-h4 small headings 13 → 17px
--fs-body-lg lead paragraphs 14 → 16px
--fs-body body text 13 → 15px
--fs-sm secondary / meta 11 → 13px
--fs-xs labels / captions 9 → 11px
═══════════════════════════════════════════════ */
:root {
/* Font sizes */
--fs-display: clamp(32px, 5.5vw, 72px);
--fs-h1: clamp(26px, 3.8vw, 52px);
--fs-h2: clamp(20px, 2.8vw, 38px);
--fs-h3: clamp(15px, 1.5vw, 22px);
--fs-h4: clamp(13px, 1.1vw, 17px);
--fs-body-lg: clamp(14px, 1.1vw, 16px);
--fs-body: clamp(13px, 0.9vw, 15px);
--fs-sm: clamp(11px, 0.75vw, 13px);
--fs-xs: clamp(9px, 0.6vw, 11px);
/* Letter spacing (Persian typography uses normal spacing to keep cursive script connected) */
--ls-display: normal;
--ls-h1: normal;
--ls-h2: normal;
--ls-h3: normal;
--ls-body: normal;
--ls-label: normal;
--ls-overline: normal;
--ls-widest: normal;
/* Line heights (increased for Persian script to prevent accent collisions and overlap) */
--lh-display: 1.25;
--lh-heading: 1.3;
--lh-subhead: 1.4;
--lh-body: 1.8;
--lh-relaxed: 1.85;
--lh-label: 1.4;
}
/* ── Base element styles ────────────────────────
Inside @layer base so Tailwind utilities (text-white, text-red, etc.)
in the @utilities layer can override these defaults. */
@layer base {
h1 {
font-size: var(--fs-h1);
font-weight: 900;
line-height: var(--lh-heading);
letter-spacing: normal;
color: var(--ink);
margin: 0;
}
h2 {
font-size: var(--fs-h2);
font-weight: 900;
line-height: var(--lh-heading);
letter-spacing: normal;
color: var(--ink);
margin: 0;
}
h3 {
font-size: var(--fs-h3);
font-weight: 700;
line-height: var(--lh-subhead);
letter-spacing: normal;
color: var(--ink);
margin: 0;
}
h4 {
font-size: var(--fs-h4);
font-weight: 700;
line-height: var(--lh-subhead);
letter-spacing: normal;
color: var(--ink);
margin: 0;
}
p {
font-size: var(--fs-body);
font-weight: 400;
line-height: var(--lh-body);
letter-spacing: normal;
color: var(--ink-3);
margin: 0;
}
}
/* ═══════════════════════════════════════════════
BASE
═══════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* McKinsey centered container margins (physical override of standard logical properties) */
.mx-auto {
margin-left: auto !important;
margin-right: auto !important;
}
html { scroll-behavior: smooth; direction: rtl; }
body {
font-family: 'Vazir', system-ui, sans-serif;
background: var(--paper);
color: var(--ink);
font-size: var(--fs-body);
line-height: var(--lh-body);
letter-spacing: normal;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
#root { min-height: 100dvh; display: flex; flex-direction: column; }
::-webkit-scrollbar { width: 3px; height: 3px; }
::-webkit-scrollbar-thumb { background: var(--ink); }
:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
::selection { background: var(--ink); color: var(--paper); }
/* ═══════════════════════════════════════════════
TYPOGRAPHY UTILITIES
═══════════════════════════════════════════════ */
/* Overline — small uppercase tracking label */
.t-overline {
font-size: var(--fs-xs);
font-weight: 700;
letter-spacing: normal;
text-transform: uppercase;
line-height: var(--lh-label);
}
/* Caption / meta text */
.t-caption {
font-size: var(--fs-sm);
font-weight: 500;
line-height: var(--lh-label);
color: var(--ink-4);
}
/* Lead paragraph */
.t-lead {
font-size: var(--fs-body-lg);
font-weight: 400;
line-height: var(--lh-relaxed);
color: var(--ink-3);
}
/* ═══════════════════════════════════════════════
TICKER ANIMATION (RTL direction)
═══════════════════════════════════════════════ */
@keyframes ticker-rtl {
0% { transform: translateX(50%); }
100% { transform: translateX(-50%); }
}
.ticker-track { animation: ticker-rtl 34s linear infinite; white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .ticker-track { animation: none; } }
/* ═══════════════════════════════════════════════
STAMP TILT
═══════════════════════════════════════════════ */
.stamp-tilt { transform: rotate(-1.5deg); }
/* ═══════════════════════════════════════════════
INFINITE SCROLL ANIMATION
═══════════════════════════════════════════════ */
@keyframes scroll {
to { transform: translateX(calc(-50% - 0.5rem)); }
}
.animate-scroll {
animation: scroll var(--animation-duration, 60s) var(--animation-direction, forwards) linear infinite;
}
.animate-scroll-risk {
animation: scroll 72s forwards linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.animate-scroll { animation: none; }
.animate-scroll-risk { animation: none; }
}
/* ═══════════════════════════════════════════════
MOBILE STACK OVERRIDE
Inline `style={{ display:'grid', gridTemplateColumns: '...' }}`
always beats Tailwind `max-md:grid-cols-1`. This utility forces
any tagged grid container down to single/two columns below 768px,
regardless of the inline declaration.
═══════════════════════════════════════════════ */
@media (max-width: 767px) {
.mq-stack {
grid-template-columns: 1fr !important;
gap: 1rem !important;
}
.mq-stack-tight {
grid-template-columns: 1fr !important;
}
.mq-stack-2 {
grid-template-columns: repeat(2, 1fr) !important;
}
}
/* ═══════════════════════════════════════════════
MARQUEE (horizontal infinite scroll)
═══════════════════════════════════════════════ */
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(calc(-100% - var(--gap, 1rem))); }
}
@keyframes marquee-reverse {
from { transform: translateX(calc(-100% - var(--gap, 1rem))); }
to { transform: translateX(0); }
}
.animate-marquee { animation: marquee var(--duration, 40s) linear infinite; }
.animate-marquee-reverse { animation: marquee-reverse var(--duration, 40s) linear infinite; }
@media (prefers-reduced-motion: reduce) {
.animate-marquee,
.animate-marquee-reverse { animation: none; }
}
/* ═══════════════════════════════════════════════
PRINT
═══════════════════════════════════════════════ */
@media print { .no-print { display: none !important; } }