feat: initial design system v1.0.0 (tokens, mixins, guide)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
// ============================================
|
||||
// @tansu/design-system — Design Tokens
|
||||
// Дизайн-система V5: Executive Premium
|
||||
//
|
||||
// ТОЛЬКО объявления: $переменные, @mixin. Ноль CSS-вывода.
|
||||
// Поэтому файл безопасно импортировать в ЛЮБОЙ .module.scss
|
||||
// сколько угодно раз — дублей в бандле не будет:
|
||||
//
|
||||
// @import '~@tansu/design-system/styles/tokens';
|
||||
// .card { background: $navy-900; @include card-hover-gold; }
|
||||
//
|
||||
// Правило: в вёрстке используем ТОЛЬКО эти переменные/миксины,
|
||||
// сырой hex (#D4A01E и т.п.) в компонентах — запрещён.
|
||||
// ============================================
|
||||
|
||||
// ---- Navy (Primary) ----
|
||||
$navy-950: #0A1B30;
|
||||
$navy-900: #0F2440;
|
||||
$navy-800: #1B3A5C;
|
||||
$navy-700: #244B73;
|
||||
$navy-600: #2D5C8A;
|
||||
$navy-100: #E8EEF4;
|
||||
$navy-50: #F4F7FA;
|
||||
|
||||
// ---- Gold (Accent) ----
|
||||
$gold-600: #B8881A;
|
||||
$gold-500: #D4A01E;
|
||||
$gold-400: #E5B635;
|
||||
$gold-300: #F0CC5E;
|
||||
$gold-100: #FDF5E0;
|
||||
$gold-50: #FEFBF0;
|
||||
|
||||
// ---- Gray (Neutral) ----
|
||||
$gray-900: #111827;
|
||||
$gray-700: #374151;
|
||||
$gray-500: #6B7280;
|
||||
$gray-400: #9CA3AF;
|
||||
$gray-300: #D1D5DB;
|
||||
$gray-200: #E5E7EB;
|
||||
$gray-100: #F3F4F6;
|
||||
$gray-50: #F9FAFB;
|
||||
|
||||
// ---- Semantic ----
|
||||
$red-500: #DC2626;
|
||||
$red-50: #FEF2F2;
|
||||
$green-600: #15803D;
|
||||
$green-50: #F0FDF4;
|
||||
$blue-600: #2563EB;
|
||||
$blue-50: #EFF6FF;
|
||||
$amber-700: #854D0E;
|
||||
|
||||
// ---- Typography ----
|
||||
// Заголовки страниц и секций — Lora (serif). Весь остальной текст — Inter (sans).
|
||||
// Подключение самих шрифтов — см. README (SPComponentLoader.loadCss в onInit).
|
||||
$font-serif: 'Lora', Georgia, serif;
|
||||
$font-sans: 'Inter', -apple-system, 'Segoe UI', sans-serif;
|
||||
|
||||
$fs-page-title: 24px; // Lora 600
|
||||
$fs-form-title: 22px; // Lora 600
|
||||
$fs-section-title: 15px; // Lora 600
|
||||
$fs-body: 14px; // Inter 400
|
||||
$fs-sm: 13px;
|
||||
$fs-label: 12px; // Inter 500
|
||||
$fs-caption: 11px;
|
||||
$fs-overline: 10.5px; // uppercase, letter-spacing 1.4-1.8px
|
||||
|
||||
// ---- Radius ----
|
||||
$r-sm: 6px;
|
||||
$r-md: 10px;
|
||||
$r-lg: 14px;
|
||||
$r-full: 100px;
|
||||
|
||||
// ---- Shadows ----
|
||||
$sh-1: 0 1px 2px rgba(15, 36, 64, .04), 0 1px 3px rgba(15, 36, 64, .06);
|
||||
$sh-2: 0 4px 16px rgba(15, 36, 64, .07);
|
||||
$sh-3: 0 12px 32px rgba(15, 36, 64, .10);
|
||||
$sh-gold: 0 4px 20px rgba(212, 160, 30, .18);
|
||||
$sh-modal: 0 24px 70px rgba(10, 27, 48, .25);
|
||||
|
||||
// ---- Gradients (фирменные) ----
|
||||
$grad-header: linear-gradient(135deg, $navy-950 0%, $navy-800 85%);
|
||||
$grad-gold: linear-gradient(135deg, $gold-400, $gold-500);
|
||||
$grad-gold-v: linear-gradient(180deg, $gold-400, $gold-600);
|
||||
$grad-hairline: linear-gradient(90deg, $gold-400, transparent 70%);
|
||||
|
||||
// ---- Spacing ----
|
||||
$sp-1: 4px;
|
||||
$sp-2: 8px;
|
||||
$sp-3: 12px;
|
||||
$sp-4: 16px;
|
||||
$sp-5: 20px;
|
||||
$sp-6: 24px;
|
||||
$sp-7: 28px;
|
||||
$sp-8: 32px;
|
||||
|
||||
// ============================================
|
||||
// Миксины — повторяющиеся паттерны из эталона.
|
||||
// Используй их вместо копирования правил в каждый компонент.
|
||||
// ============================================
|
||||
|
||||
// Шапка экрана: navy-градиент + золотая линия снизу.
|
||||
@mixin page-header {
|
||||
background: $grad-header;
|
||||
border-radius: $r-lg;
|
||||
padding: 26px 30px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, $gold-500, transparent 60%);
|
||||
}
|
||||
}
|
||||
|
||||
// Карточка: подъём + тень + золотая рамка при наведении.
|
||||
@mixin card-hover-gold {
|
||||
transition: .22s;
|
||||
|
||||
&:hover {
|
||||
box-shadow: $sh-3;
|
||||
transform: translateY(-2px);
|
||||
border-color: $gold-300;
|
||||
}
|
||||
}
|
||||
|
||||
// Акцентная кнопка (золотой градиент).
|
||||
@mixin btn-accent {
|
||||
background: $grad-gold;
|
||||
color: $navy-950;
|
||||
font-weight: 600;
|
||||
border: 1px solid $gold-500;
|
||||
|
||||
&:hover {
|
||||
box-shadow: $sh-gold;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
// Золотое фокус-кольцо для инпутов/селектов.
|
||||
@mixin input-focus-gold {
|
||||
&:focus {
|
||||
outline: 0;
|
||||
border-color: $gold-500;
|
||||
box-shadow: 0 0 0 3px rgba(212, 160, 30, .12);
|
||||
}
|
||||
}
|
||||
|
||||
// Тонкий золотой разделитель (hairline).
|
||||
@mixin hairline {
|
||||
height: 1px;
|
||||
background: $grad-hairline;
|
||||
border: 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// ============================================
|
||||
// @tansu/design-system — Runtime CSS Variables
|
||||
//
|
||||
// Этот файл ПРОИЗВОДИТ CSS (:root{...}), поэтому подключай его
|
||||
// РОВНО ОДИН РАЗ на веб-часть — в корневом .module.scss компонента:
|
||||
//
|
||||
// @import '~@tansu/design-system/styles/global';
|
||||
//
|
||||
// Нужен только если читаешь переменные в рантайме — например
|
||||
// в инлайн-стилях (style={{ color: 'var(--gold-500)' }}) или для
|
||||
// динамической темизации. Для обычной SCSS-вёрстки хватает _tokens.scss.
|
||||
// ============================================
|
||||
|
||||
@import 'tokens';
|
||||
|
||||
:root {
|
||||
--navy-950: #{$navy-950};
|
||||
--navy-900: #{$navy-900};
|
||||
--navy-800: #{$navy-800};
|
||||
--navy-700: #{$navy-700};
|
||||
--navy-600: #{$navy-600};
|
||||
--navy-100: #{$navy-100};
|
||||
--navy-50: #{$navy-50};
|
||||
|
||||
--gold-600: #{$gold-600};
|
||||
--gold-500: #{$gold-500};
|
||||
--gold-400: #{$gold-400};
|
||||
--gold-300: #{$gold-300};
|
||||
--gold-100: #{$gold-100};
|
||||
--gold-50: #{$gold-50};
|
||||
|
||||
--gray-900: #{$gray-900};
|
||||
--gray-700: #{$gray-700};
|
||||
--gray-500: #{$gray-500};
|
||||
--gray-400: #{$gray-400};
|
||||
--gray-300: #{$gray-300};
|
||||
--gray-200: #{$gray-200};
|
||||
--gray-100: #{$gray-100};
|
||||
--gray-50: #{$gray-50};
|
||||
|
||||
--red-500: #{$red-500};
|
||||
--red-50: #{$red-50};
|
||||
--green-600: #{$green-600};
|
||||
--green-50: #{$green-50};
|
||||
--blue-600: #{$blue-600};
|
||||
--blue-50: #{$blue-50};
|
||||
--amber-700: #{$amber-700};
|
||||
|
||||
--sh-1: #{$sh-1};
|
||||
--sh-2: #{$sh-2};
|
||||
--sh-3: #{$sh-3};
|
||||
--sh-gold: #{$sh-gold};
|
||||
--sh-modal: #{$sh-modal};
|
||||
|
||||
--r-sm: #{$r-sm};
|
||||
--r-md: #{$r-md};
|
||||
--r-lg: #{$r-lg};
|
||||
}
|
||||
Reference in New Issue
Block a user