Files
MathApp_frontend/src/styles/index.css

158 lines
8.0 KiB
CSS
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* فونت از خودِ اپ سرو می‌شود؛ Google Fonts از داخلِ ایران کند یا مسدود است. */
@import 'vazirmatn/Vazirmatn-Variable-font-face.css';
@import 'tailwindcss';
/*
* پالتِ اپ — همان رنگ‌های طراحیِ اولیه، یک‌جا.
* هر رنگ یک کلاسِ Tailwind می‌سازد: bg-coral، text-ink، border-line، …
*/
@theme {
--font-sans: 'Vazirmatn', system-ui, sans-serif;
--color-coral: #ED6956; /* رنگِ اصلیِ برند */
--color-steel: #91ADC6; /* نقشه */
--color-teal: #97C0C0; /* درس‌ها */
--color-violet: #9B7BFF; /* دستیار (پی) */
--color-orange: #FF7A3D; /* جدولِ امتیاز (دلتا) */
--color-indigo: #4C5FD5; /* سیگما */
--color-rose: #F3A9B0; /* اسپلش */
--color-gold: #E8A400;
--color-mint: #5FBF8F;
--color-ink: #1a1a2e; /* متنِ اصلی */
--color-body: #3a3a5c; /* متنِ بدنه */
/* متنِ کم‌رنگ. تا ۲۰۲۶-۱۰-۰۳ ‎#9e9ec0 بود: کنتراست ۲٫۶ روی سفید، زیرِ حدِ ۴٫۵ِ WCAG، و
همین رنگ زیرنویسِ ۱۰–۱۲ پیکسلیِ همه‌ی صفحه‌ها و آیکونِ تب‌های غیرفعال است. این یکی
روی سفید ۴٫۵ و روی پس‌زمینه‌ی صفحه ۴٫۲ است. */
--color-muted: #727299;
--color-faint: #b0b0c8;
--color-line: #e9e6f7; /* حاشیه‌ی کارت */
--color-soft: #f0eeff; /* پس‌زمینه‌ی ملایم */
--color-page: #f6f5fb; /* پس‌زمینه‌ی صفحه؛ کمی گرم‌تر از آبیِ قبلی */
}
@layer base {
html, body, #root {
height: 100%;
}
body {
margin: 0;
background: #14142a;
color: var(--color-ink);
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
}
button {
cursor: pointer;
font: inherit;
/* بی‌تأخیرِ دابل‌تپ و بی‌زوم با دو ضربه روی دکمه‌ها */
touch-action: manipulation;
}
button:disabled {
cursor: not-allowed;
}
/* کشیدنِ صفحه به پایین در کروم اندروید کلِ اپ را رفرش می‌کرد (pull-to-refresh)
و وسطِ آزمون جوابِ جاری را می‌پراند؛ صفحه‌های داخلی خودشان اسکرول دارند. */
html, body {
overscroll-behavior: none;
}
/* حلقه‌ی فوکوس فقط برای صفحه‌کلید (focus-visible)، نه برای لمس. */
:focus-visible {
outline: 2px solid var(--color-indigo);
outline-offset: 2px;
}
}
/* کاربری که در تنظیماتِ گوشی «کاهشِ حرکت» را زده: انیمیشن‌ها و transitionهای CSS
تقریباً آنی می‌شوند. انیمیشن‌های motion را MotionConfig در App خاموش می‌کند. */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
@layer base {
input, textarea {
font: inherit;
}
/* متنِ چندخطی (پاراگراف، گام‌های درس، متنِ سوال، حبابِ پی) دو‌طرف‌چین است تا لبه‌ی چپ
مرتب باشد. این‌ها در لایه‌ی base‌اند، پس هر جا کلاسِ text-center / text-left داده شده
برنده است و تیترها و برچسب‌های کوتاه سرِ جایشان می‌مانند. خطِ آخر طبقِ معمول راست‌چین
می‌ماند. text-justify فقط فاصله‌ی بینِ کلمه‌ها را باز می‌کند (کشیده‌نویسی در CSS نیست). */
p, li, .whitespace-pre-line {
text-align: justify;
text-justify: inter-word;
/* از تک‌کلمه‌ی یتیم در خطِ آخر جلوگیری می‌کند */
text-wrap: pretty;
}
/* پاراگرافِ داخلِ بخشِ وسط‌چین (حالتِ خالی، آنبوردینگ، اسپلش) وسط‌چین می‌ماند؛
بدونِ این، قاعده‌ی بالا ارثِ text-center را می‌شکست. */
.text-center :is(p, li, .whitespace-pre-line) {
text-align: center;
}
.text-left :is(p, li, .whitespace-pre-line) {
text-align: left;
}
}
@utility no-scrollbar {
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
/* فاصله‌ی امن بالای صفحه در گوشی‌های ناچ‌دار (وقتی اپ به صفحه‌ی اصلی اضافه شده). */
@utility pt-safe {
padding-top: max(env(safe-area-inset-top), 0px);
}
@utility pb-safe {
padding-bottom: max(env(safe-area-inset-bottom), 0px);
}
/* نمادهای شناورِ سربرگ (ui.tsx). فقط transform، پس روی GPU می‌ماند. */
@keyframes glyph-float {
0%, 100% { transform: translateY(0) rotate(-6deg); }
50% { transform: translateY(-7px) rotate(6deg); }
}
.glyph {
animation: glyph-float 6s ease-in-out infinite;
will-change: transform;
}
/* ناحیه‌ی لمسِ بزرگ‌تر بدونِ تغییرِ ظاهر: دکمه‌های کوچکِ سربرگ (۲۸–۳۲ پیکسل) برای انگشت کوچک‌اند. */
.hit { position: relative; }
.hit::after { content: ''; position: absolute; inset: -7px -3px; }
/* نوارِ اشتراک و نشانِ تدریسینو: فقط transform/opacity تا روی GPU بماند و روانی حفظ شود. */
@keyframes bar-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.bar-fill { transform-origin: right; animation: bar-fill 0.9s cubic-bezier(.2,.8,.2,1) both; }
@keyframes shine { 0% { transform: translateX(120%); } 60%, 100% { transform: translateX(-220%); } }
.shine { animation: shine 3.2s ease-in-out infinite; will-change: transform; }
@keyframes spark { 0%, 100% { opacity: .25; transform: scale(.7); } 50% { opacity: 1; transform: scale(1); } }
.spark { animation: spark 2.4s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
/* نوارِ انتظارِ میانِ دو صفحه (MainApp → HoldBar). */
@keyframes hold-bar { 0% { transform: translateX(120%); } 100% { transform: translateX(-320%); } }
.hold-bar { animation: hold-bar 0.9s cubic-bezier(.4,0,.2,1) infinite; will-change: transform; }
/* شعله‌ی زنجیره (StreakFlame): دو لایه با ریتمِ متفاوت، از پایین تکان می‌خورند. */
@keyframes flame-a { 0%, 100% { transform: scale(1, 1) skewX(0deg); } 33% { transform: scale(.97, 1.04) skewX(-2deg); } 66% { transform: scale(1.02, .97) skewX(2deg); } }
@keyframes flame-b { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(.94, 1.08); } }
.flame-outer { transform-box: fill-box; transform-origin: 50% 100%; animation: flame-a 1.4s ease-in-out infinite; }
.flame-inner { transform-box: fill-box; transform-origin: 50% 100%; animation: flame-b .9s ease-in-out infinite; }
@keyframes ice-glint { 0%, 70%, 100% { opacity: 0; } 80% { opacity: 1; } }
.ice-glint { animation: ice-glint 2.8s ease-in-out infinite; }
@keyframes spark-rise { 0% { transform: translateY(0) scale(1); opacity: 0; } 15% { opacity: 1; } 100% { transform: translateY(-180px) scale(.3); opacity: 0; } }
.spark-rise { animation: spark-rise 1.8s ease-out infinite; }
/* همراه‌های کنارِ مسیرِ جزیره‌ها (IslandPath): فقط transform، تا روی گوشیِ ضعیف هم روی GPU بماند. */
@keyframes buddy-hop { 0%, 55%, 100% { transform: translateY(0) scale(1, 1); } 20% { transform: translateY(-12px) scale(.96, 1.05); } 40% { transform: translateY(0) scale(1.06, .94); } }
@keyframes buddy-sway { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
.buddy-hop { animation: buddy-hop 1.6s ease-in-out infinite; transform-origin: 50% 100%; }
.buddy-sway { animation: buddy-sway 3.2s ease-in-out infinite; transform-origin: 50% 100%; }