griffincss-utils 0.21.4 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "griffincss-utils",
3
- "version": "0.21.4",
3
+ "version": "0.22.0",
4
4
  "description": "Griffincss Utils — утилитарные классы: отступы, типографика, цвета, видимость, скругления",
5
5
  "homepage": "https://gitverse.ru/BarneyScott/GriffinCSS",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "src/"
32
32
  ],
33
33
  "peerDependencies": {
34
- "griffincss-core": "^0.21.4"
34
+ "griffincss-core": "^0.22.0"
35
35
  },
36
36
  "keywords": [
37
37
  "css",
@@ -38,8 +38,8 @@
38
38
  }
39
39
 
40
40
  // Предопределённые радиусы (шаг 0.25rem, от 0 до 16 = 4rem)
41
- $gr-radius-base: 0.25rem;
42
- $gr-radius-max: 16;
41
+ $gr-radius-base: 0.25rem !default;
42
+ $gr-radius-max: 16 !default;
43
43
 
44
44
  @for $i from 0 through $gr-radius-max {
45
45
  $val: $i * $gr-radius-base;
@@ -30,18 +30,18 @@
30
30
  }
31
31
  }
32
32
 
33
- // Стороны. Физические t/r/b/l остаются буквальными, логические s/e идут
34
- // рядом: в LTR они совпадают с l/r, в RTL меняются местами сами.
33
+ // Стороны. Верх и низ (t/b) — физические: блочная ось в RTL
34
+ // не разворачивается. Боковые — только логические s/e: в LTR они
35
+ // совпадают с l/r, в RTL меняются местами сами. Физические l/r
36
+ // удалены Этапом 36.
35
37
  $gr-border-sides: (
36
38
  t: top,
37
- r: right,
38
39
  b: bottom,
39
- l: left,
40
40
  s: inline-start,
41
41
  e: inline-end
42
- );
42
+ ) !default;
43
43
 
44
- // Ширина у стороны задаётся своим классом, а не парой .gr-border-l + .gr-border-4:
44
+ // Ширина у стороны задаётся своим классом, а не парой .gr-border-s + .gr-border-4:
45
45
  // класс ширины пишет сокращённое свойство border и сбрасывает вместе с ним все
46
46
  // четыре стороны, так что «толстая граница слева» такой парой не получается.
47
47
  @each $gr-key, $gr-side in $gr-border-sides {
@@ -67,7 +67,7 @@ $gr-border-sides: (
67
67
  $gr-border-axes: (
68
68
  x: inline,
69
69
  y: block
70
- );
70
+ ) !default;
71
71
 
72
72
  @each $gr-key, $gr-axis in $gr-border-axes {
73
73
  .gr-border-#{$gr-key} {
package/scss/_colors.scss CHANGED
@@ -1,68 +1,41 @@
1
1
  // Griffincss — Color Utilities
2
2
  // HSL-based palette with background, text, and border utilities
3
-
4
- // Neutral gray scale
5
- $gr-grays: (
6
- "white": var(--gr-hsl-white),
7
- gray-50: var(--gr-hsl-gray-50),
8
- gray-100: var(--gr-hsl-gray-100),
9
- gray-200: var(--gr-hsl-gray-200),
10
- gray-300: var(--gr-hsl-gray-300),
11
- gray-400: var(--gr-hsl-gray-400),
12
- gray-500: var(--gr-hsl-gray-500),
13
- gray-600: var(--gr-hsl-gray-600),
14
- gray-700: var(--gr-hsl-gray-700),
15
- gray-800: var(--gr-hsl-gray-800),
16
- gray-900: var(--gr-hsl-gray-900),
17
- "black": var(--gr-hsl-black)
18
- );
19
-
20
- // Accent colors
21
- $gr-accents: (
22
- primary: var(--gr-hsl-primary),
23
- primary-light: var(--gr-hsl-primary-light),
24
- primary-dark: var(--gr-hsl-primary-dark),
25
- secondary: var(--gr-hsl-secondary),
26
- secondary-light: var(--gr-hsl-secondary-light),
27
- secondary-dark: var(--gr-hsl-secondary-dark),
28
- success: var(--gr-hsl-success),
29
- success-light: var(--gr-hsl-success-light),
30
- success-dark: var(--gr-hsl-success-dark),
31
- warning: var(--gr-hsl-warning),
32
- warning-light: var(--gr-hsl-warning-light),
33
- warning-dark: var(--gr-hsl-warning-dark),
34
- danger: var(--gr-hsl-danger),
35
- danger-light: var(--gr-hsl-danger-light),
36
- danger-dark: var(--gr-hsl-danger-dark),
37
- info: var(--gr-hsl-info),
38
- info-light: var(--gr-hsl-info-light),
39
- info-dark: var(--gr-hsl-info-dark)
40
- );
3
+ //
4
+ // Карты палитры вынесены в _palette.scss: те же имена нужны градиентам.
5
+ // Форвард сохраняет публичную настройку — @use 'griffincss-utils/scss/colors'
6
+ // with ($gr-accents: …) настраивает именно их.
7
+
8
+ // Форвард стоит ПЕРЕД use: настройка снаружи (@use 'colors' with (…))
9
+ // проходит через него, а @use подхватывает уже настроенный модуль.
10
+ // В обратном порядке palette грузится ненастроенным, и настройка падает
11
+ // сообщением «This module was already loaded».
12
+ @forward 'palette';
13
+ @use 'palette';
41
14
 
42
15
  // Background utilities
43
- @each $name, $hsl in $gr-grays {
16
+ @each $name, $hsl in palette.$gr-grays {
44
17
  .gr-bg-#{$name} { background-color: hsl(#{$hsl}); }
45
18
  }
46
19
 
47
- @each $name, $hsl in $gr-accents {
20
+ @each $name, $hsl in palette.$gr-accents {
48
21
  .gr-bg-#{$name} { background-color: hsl(#{$hsl}); }
49
22
  }
50
23
 
51
24
  // Text color utilities
52
- @each $name, $hsl in $gr-grays {
25
+ @each $name, $hsl in palette.$gr-grays {
53
26
  .gr-text-#{$name} { color: hsl(#{$hsl}); }
54
27
  }
55
28
 
56
- @each $name, $hsl in $gr-accents {
29
+ @each $name, $hsl in palette.$gr-accents {
57
30
  .gr-text-#{$name} { color: hsl(#{$hsl}); }
58
31
  }
59
32
 
60
33
  // Border color utilities
61
- @each $name, $hsl in $gr-grays {
34
+ @each $name, $hsl in palette.$gr-grays {
62
35
  .gr-border-#{$name} { border-color: hsl(#{$hsl}); }
63
36
  }
64
37
 
65
- @each $name, $hsl in $gr-accents {
38
+ @each $name, $hsl in palette.$gr-accents {
66
39
  .gr-border-#{$name} { border-color: hsl(#{$hsl}); }
67
40
  }
68
41
 
@@ -2,7 +2,7 @@
2
2
  // Прозрачность, вписывание медиа и пропорции блока.
3
3
 
4
4
  // Прозрачность
5
- $gr-opacities: (0: 0, 25: 0.25, 50: 0.5, 75: 0.75, 100: 1);
5
+ $gr-opacities: (0: 0, 25: 0.25, 50: 0.5, 75: 0.75, 100: 1) !default;
6
6
 
7
7
  @each $gr-step, $gr-value in $gr-opacities {
8
8
  .gr-opacity-#{$gr-step} { opacity: $gr-value; }
@@ -0,0 +1,86 @@
1
+ // Griffincss — Filters
2
+ // Размытие, обесцвечивание и яркость; контраст с насыщенностью — по заказу.
3
+ //
4
+ // Суффиксов брейкпоинта и контейнера у модуля НЕТ и не будет — по той же
5
+ // причине, что у трансформаций: приглушённый логотип выглядит одинаково
6
+ // на любой ширине окна.
7
+ //
8
+ // Все функции живут в одном свойстве filter, поэтому класс задаёт
9
+ // настраиваемое свойство, а собирающее правило склеивает их в значение:
10
+ // иначе .gr-blur-2 и .gr-grayscale-100 затёрли бы друг друга.
11
+
12
+ @use 'sass:list';
13
+ @use 'sass:map';
14
+ @use 'sass:string';
15
+
16
+ $gr-blurs: (1: 2px, 2: 4px, 3: 8px, 4: 16px) !default;
17
+ $gr-grayscales: (50: 0.5, 100: 1) !default;
18
+ $gr-brightnesses: (75: 0.75, 90: 0.9, 110: 1.1, 125: 1.25) !default;
19
+
20
+ // Контраст и насыщенность машинерия поддерживает полностью, но по умолчанию
21
+ // не выводит: три группы Этапа 32 и без них выбирают бюджет утилит целиком,
22
+ // а спрос на них ниже, чем на размытие и обесцвечивание. Пустая карта стоит
23
+ // ноль байт; непустая включает и классы, и функцию в собирающем правиле:
24
+ //
25
+ // @include meta.load-css('griffincss-utils/scss/filters', $with: (
26
+ // 'gr-saturations': (0: 0, 150: 1.5)
27
+ // ));
28
+ $gr-contrasts: () !default;
29
+ $gr-saturations: () !default;
30
+
31
+ // Имя функции CSS — оно же имя настраиваемого свойства: blur → --gr-blur.
32
+ // Второго словаря для этого не нужно.
33
+ $_gr-filters: (
34
+ blur: $gr-blurs,
35
+ grayscale: $gr-grayscales,
36
+ brightness: $gr-brightnesses,
37
+ contrast: $gr-contrasts,
38
+ saturate: $gr-saturations
39
+ );
40
+
41
+ // Нейтральное значение функции — то, при котором она ничего не делает.
42
+ $_gr-neutral: (blur: 0, grayscale: 0, brightness: 1, contrast: 1, saturate: 1);
43
+
44
+ // Перечень селекторов и значение filter собираются вместе: пустая карта
45
+ // не даёт ни классов, ни своей функции.
46
+ $_gr-filtered: ();
47
+ $_gr-value: ();
48
+
49
+ @each $gr-fn, $gr-steps in $_gr-filters {
50
+ @if list.length($gr-steps) > 0 {
51
+ $_gr-value: list.append($_gr-value, string.unquote('#{$gr-fn}(var(--gr-#{$gr-fn}))'), space);
52
+
53
+ @each $gr-step, $gr-item in $gr-steps {
54
+ $_gr-filtered: list.append($_gr-filtered, string.unquote('.gr-#{$gr-fn}-#{$gr-step}'), comma);
55
+ }
56
+ }
57
+ }
58
+
59
+ // Нейтральные значения в собирающем правиле — сброс наследования:
60
+ // настраиваемые свойства наследуются, и вложенный .gr-grayscale-100
61
+ // без сброса получил бы ещё и размытие предка. Правило стоит ДО
62
+ // классов-значений: специфичность у них одна, решает порядок.
63
+ //
64
+ // Общий список селекторов, а не повтор объявления в каждом классе, —
65
+ // по замеру: на девятнадцати правилах список стоит 287 Б gzip против
66
+ // 311 Б у повтора. Значение из пяти функций длиннее, чем перечисление
67
+ // селекторов, и выгоднее написать его один раз (у трансформаций
68
+ // тот же замер дал обратный ответ — там значение короткое).
69
+ #{$_gr-filtered} {
70
+ @each $gr-fn, $gr-steps in $_gr-filters {
71
+ @if list.length($gr-steps) > 0 {
72
+ --gr-#{$gr-fn}: #{map.get($_gr-neutral, $gr-fn)};
73
+ }
74
+ }
75
+
76
+ filter: $_gr-value;
77
+ }
78
+
79
+ @each $gr-fn, $gr-steps in $_gr-filters {
80
+ @each $gr-step, $gr-value in $gr-steps {
81
+ .gr-#{$gr-fn}-#{$gr-step} { --gr-#{$gr-fn}: #{$gr-value}; }
82
+ }
83
+ }
84
+
85
+ // Снять фильтр целиком — например, у потомка размытой подложки.
86
+ .gr-filter-none { filter: none; }
@@ -0,0 +1,80 @@
1
+ // Griffincss — Gradients
2
+ // Направление линейного градиента и три точки: from / via / to.
3
+ //
4
+ // Суффиксов брейкпоинта и контейнера у модуля НЕТ и не будет — довод тот же,
5
+ // что у трансформаций и фильтров.
6
+ //
7
+ // Своей палитры у группы нет: цвет берётся из тех же карт, что и .gr-bg-*,
8
+ // то есть из переменных --gr-hsl-*. Перенастроенная палитра меняет градиенты
9
+ // вместе со всем остальным, а не отдельно от него.
10
+
11
+ @use 'sass:list';
12
+ @use 'sass:map';
13
+ @use 'sass:string';
14
+ @use 'palette';
15
+
16
+ // Направление. Ключевые слова физические: градиент — геометрия фона,
17
+ // а не строка текста, и от направления письма не разворачивается.
18
+ $gr-gradient-directions: (
19
+ r: to right,
20
+ l: to left,
21
+ t: to top,
22
+ b: to bottom,
23
+ br: to bottom right,
24
+ tr: to top right
25
+ ) !default;
26
+
27
+ // Цвета точек. Отдельная карта, а не вся палитра целиком: восемь цветов
28
+ // на три точки — это 24 класса, а вся палитра акцентов дала бы 54 и вывела
29
+ // utils за бюджет. Своей палитры у группы при этом нет: значения берутся
30
+ // из тех же карт, что и .gr-bg-*, по именам.
31
+ //
32
+ // Имя, которого в палитре не оказалось, молча пропускается: перенастроивший
33
+ // $gr-accents под свой бренд не получит .gr-from-primary, ссылающийся
34
+ // в пустоту. Нужны свои имена — переопределяется $gr-gradient-colors,
35
+ // механизм от этого не меняется.
36
+ $_gr-picked: ("white", "black", primary, secondary, success, warning, danger, info);
37
+ $_gr-colors: ();
38
+
39
+ @each $gr-name in $_gr-picked {
40
+ $_gr-hsl: map.get(palette.$gr-grays, $gr-name);
41
+
42
+ @if not $_gr-hsl {
43
+ $_gr-hsl: map.get(palette.$gr-accents, $gr-name);
44
+ }
45
+
46
+ @if $_gr-hsl {
47
+ $_gr-colors: map.set($_gr-colors, $gr-name, $_gr-hsl);
48
+ }
49
+ }
50
+
51
+ $gr-gradient-colors: $_gr-colors !default;
52
+
53
+ // Перечень направлений — он же перечень селекторов собирающего правила.
54
+ $_gr-gradients: ();
55
+
56
+ @each $gr-key, $gr-value in $gr-gradient-directions {
57
+ $_gr-gradients: list.append($_gr-gradients, string.unquote('.gr-gradient-to-#{$gr-key}'), comma);
58
+ }
59
+
60
+ // Собирающее правило. Прозрачные концы — не украшение, а сброс
61
+ // наследования: настраиваемые свойства наследуются, и вложенный градиент
62
+ // без своих точек перекрасился бы цветами предка. Правило стоит ДО
63
+ // классов-значений: специфичность у них одна, решает порядок.
64
+ #{$_gr-gradients} {
65
+ --gr-from: transparent;
66
+ --gr-via: initial;
67
+ --gr-to: transparent;
68
+
69
+ background-image: linear-gradient(var(--gr-gradient-dir), var(--gr-from), var(--gr-via, ) var(--gr-to));
70
+ }
71
+
72
+ @each $gr-key, $gr-value in $gr-gradient-directions {
73
+ .gr-gradient-to-#{$gr-key} { --gr-gradient-dir: #{$gr-value}; }
74
+ }
75
+
76
+ @each $gr-name, $gr-hsl in $gr-gradient-colors {
77
+ .gr-from-#{$gr-name} { --gr-from: hsl(#{$gr-hsl}); }
78
+ .gr-via-#{$gr-name} { --gr-via: hsl(#{$gr-hsl}),; }
79
+ .gr-to-#{$gr-name} { --gr-to: hsl(#{$gr-hsl}); }
80
+ }
@@ -1,7 +1,7 @@
1
1
  // Griffincss — Interactivity
2
2
  // Курсор, приём событий указателя, выделение текста, прокрутка.
3
3
 
4
- $gr-cursors: (pointer, default, text, move, grab, grabbing, wait, progress, help, not-allowed);
4
+ $gr-cursors: (pointer, default, text, move, grab, grabbing, wait, progress, help, not-allowed) !default;
5
5
 
6
6
  @each $gr-value in $gr-cursors {
7
7
  .gr-cursor-#{$gr-value} { cursor: $gr-value; }
@@ -0,0 +1,50 @@
1
+ // Griffincss — Palette
2
+ // Карты палитры: имена цветов и переменные-источники. Вывода у модуля нет —
3
+ // только значения.
4
+ //
5
+ // Отдельным файлом, потому что карты нужны двум модулям: _colors.scss красит
6
+ // фон, текст и границы, _gradients.scss берёт те же имена для точек градиента.
7
+ // Пока карты лежали в _colors.scss, второй модуль мог достать их только
8
+ // через @use — а тот повторял и весь вывод цветов, удваивая полтора килобайта.
9
+ //
10
+ // Публичный путь к настройке не менялся: _colors.scss форвардит этот модуль,
11
+ // поэтому @use 'griffincss-utils/scss/colors' with ($gr-accents: …) работает
12
+ // как прежде.
13
+
14
+ // Нейтральная шкала (светлота по Фибоначчи)
15
+ $gr-grays: (
16
+ "white": var(--gr-hsl-white),
17
+ gray-50: var(--gr-hsl-gray-50),
18
+ gray-100: var(--gr-hsl-gray-100),
19
+ gray-200: var(--gr-hsl-gray-200),
20
+ gray-300: var(--gr-hsl-gray-300),
21
+ gray-400: var(--gr-hsl-gray-400),
22
+ gray-500: var(--gr-hsl-gray-500),
23
+ gray-600: var(--gr-hsl-gray-600),
24
+ gray-700: var(--gr-hsl-gray-700),
25
+ gray-800: var(--gr-hsl-gray-800),
26
+ gray-900: var(--gr-hsl-gray-900),
27
+ "black": var(--gr-hsl-black)
28
+ ) !default;
29
+
30
+ // Акценты (шаг 72° по цветовому кругу)
31
+ $gr-accents: (
32
+ primary: var(--gr-hsl-primary),
33
+ primary-light: var(--gr-hsl-primary-light),
34
+ primary-dark: var(--gr-hsl-primary-dark),
35
+ secondary: var(--gr-hsl-secondary),
36
+ secondary-light: var(--gr-hsl-secondary-light),
37
+ secondary-dark: var(--gr-hsl-secondary-dark),
38
+ success: var(--gr-hsl-success),
39
+ success-light: var(--gr-hsl-success-light),
40
+ success-dark: var(--gr-hsl-success-dark),
41
+ warning: var(--gr-hsl-warning),
42
+ warning-light: var(--gr-hsl-warning-light),
43
+ warning-dark: var(--gr-hsl-warning-dark),
44
+ danger: var(--gr-hsl-danger),
45
+ danger-light: var(--gr-hsl-danger-light),
46
+ danger-dark: var(--gr-hsl-danger-dark),
47
+ info: var(--gr-hsl-info),
48
+ info-light: var(--gr-hsl-info-light),
49
+ info-dark: var(--gr-hsl-info-dark)
50
+ ) !default;
@@ -7,7 +7,7 @@
7
7
 
8
8
  @use 'griffincss-core/scss/breakpoints' as bp;
9
9
 
10
- $gr-positions: (static, relative, absolute, fixed, sticky);
10
+ $gr-positions: (static, relative, absolute, fixed, sticky) !default;
11
11
 
12
12
  @mixin gr-position-scale($suffix: '') {
13
13
  @each $gr-value in $gr-positions {
@@ -31,14 +31,16 @@ $gr-positions: (static, relative, absolute, fixed, sticky);
31
31
  inset-block: 0;
32
32
  }
33
33
 
34
- @each $gr-side in (top, right, bottom, left) {
34
+ // Верх и низ — физические: блочная ось в RTL не разворачивается.
35
+ @each $gr-side in (top, bottom) {
35
36
  .gr-#{$gr-side}-0 { #{$gr-side}: 0; }
36
37
  .gr-#{$gr-side}-auto { #{$gr-side}: auto; }
37
38
  }
38
39
 
39
- // Односторонние left/right остаются физическими намеренно: кнопка «закрыть»
40
- // в углу окна обязана держаться угла, а не начала строки. Привязку к строке
41
- // даёт логическая пара start/end — в LTR она совпадает с left/right.
40
+ // Привязка к строке — логическая пара start/end: в LTR она совпадает
41
+ // с left/right, в RTL меняется местами сама. Физические left/right
42
+ // удалены Этапом 36; стороне, которая обязана быть физической
43
+ // (угол окна при любом направлении письма), нужен свой CSS.
42
44
  @each $gr-key, $gr-side in (start: inset-inline-start, end: inset-inline-end) {
43
45
  .gr-#{$gr-key}-0 { #{$gr-side}: 0; }
44
46
  .gr-#{$gr-key}-auto { #{$gr-side}: auto; }
@@ -6,7 +6,7 @@
6
6
  // в отдельный --gr-shadow-color в формате HSL-компонент: в тёмной теме
7
7
  // (Этап 5) меняется одна переменная, а не шесть готовых теней.
8
8
 
9
- $gr-shadows: (xs, sm, md, lg, xl, 2xl, inner);
9
+ $gr-shadows: (xs, sm, md, lg, xl, 2xl, inner) !default;
10
10
 
11
11
  @each $gr-name in $gr-shadows {
12
12
  .gr-shadow-#{$gr-name} {
@@ -34,33 +34,31 @@ $gr-spacing-steps: (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16) !default;
34
34
  }
35
35
 
36
36
 
37
+ // Верх и низ — физические и остаются: блочная ось в RTL
38
+ // не разворачивается. Односторонние left/right удалены Этапом 36:
39
+ // начало и конец строки задают логические ms/me/ps/pe ниже.
37
40
  .gr-mt-#{$i}#{$suffix} { margin-top: $val; }
38
- .gr-mr-#{$i}#{$suffix} { margin-right: $val; }
39
41
  .gr-mb-#{$i}#{$suffix} { margin-bottom: $val; }
40
- .gr-ml-#{$i}#{$suffix} { margin-left: $val; }
41
42
 
42
43
  .gr-pt-#{$i}#{$suffix} { padding-top: $val; }
43
- .gr-pr-#{$i}#{$suffix} { padding-right: $val; }
44
44
  .gr-pb-#{$i}#{$suffix} { padding-bottom: $val; }
45
- .gr-pl-#{$i}#{$suffix} { padding-left: $val; }
46
45
 
47
46
  // Логические односторонние отступы: start — начало строки, end — конец.
48
47
  // В LTR совпадают с left/right, в RTL меняются местами сами, без правил
49
48
  // на [dir] и :dir().
50
49
  //
51
- // Адаптивных вариантов у них нет намеренно. Полный набор — 12 ступеней
52
- // на четырёх свойствах и пяти брейкпоинтах, 240 селекторов и +1086 Б
53
- // gzip; переход mx/px на одно свойство компенсирует из них 123 Б.
54
- // Ступени сохранены все до одной — класс заменяется на логический
55
- // один-в-один, — а платой за это стал отказ от суффикса брейкпоинта:
56
- // так прирост держится в 240 Б gzip, а raw-размер файла даже падает.
57
- @if $suffix == '' {
58
- .gr-ms-#{$i} { margin-inline-start: $val; }
59
- .gr-me-#{$i} { margin-inline-end: $val; }
60
-
61
- .gr-ps-#{$i} { padding-inline-start: $val; }
62
- .gr-pe-#{$i} { padding-inline-end: $val; }
63
- }
50
+ // Адаптивные и контейнерные варианты добавлены Этапом 36: без них
51
+ // снятие физических классов забрало бы у потребителя односторонний
52
+ // отступ от брейкпоинта, а не перевело его на логический. Прирост
53
+ // замерен честной сборкой — +1 527 Б gzip при расчёте +1 645 правкой
54
+ // собранного файла: селекторы те же 400, но вперемешку со шкалой
55
+ // обратные ссылки gzip короче. Вместе с удалением физических
56
+ // классов размен уходит в минус.
57
+ .gr-ms-#{$i}#{$suffix} { margin-inline-start: $val; }
58
+ .gr-me-#{$i}#{$suffix} { margin-inline-end: $val; }
59
+
60
+ .gr-ps-#{$i}#{$suffix} { padding-inline-start: $val; }
61
+ .gr-pe-#{$i}#{$suffix} { padding-inline-end: $val; }
64
62
 
65
63
  // Осевые — одно логическое свойство вместо пары физических: в LTR
66
64
  // результат тот же, в RTL корректный, а объявлений вдвое меньше.
@@ -84,25 +82,15 @@ $gr-spacing-steps: (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16) !default;
84
82
  margin-inline: auto;
85
83
  }
86
84
 
87
- .gr-ml-auto#{$suffix} {
88
- margin-left: auto;
89
- }
90
-
91
- .gr-mr-auto#{$suffix} {
92
- margin-right: auto;
93
- }
94
-
95
85
  // Прижатие к краю строки, а не к стороне экрана: в RTL .gr-ms-auto
96
- // отодвигает элемент вправо, .gr-me-auto — влево. Суффикса брейкпоинта
97
- // нет по той же причине, что и у остальных логических классов.
98
- @if $suffix == '' {
99
- .gr-ms-auto {
100
- margin-inline-start: auto;
101
- }
86
+ // отодвигает элемент вправо, .gr-me-auto — влево. Суффикс брейкпоинта —
87
+ // как у всей шкалы, с Этапа 36.
88
+ .gr-ms-auto#{$suffix} {
89
+ margin-inline-start: auto;
90
+ }
102
91
 
103
- .gr-me-auto {
104
- margin-inline-end: auto;
105
- }
92
+ .gr-me-auto#{$suffix} {
93
+ margin-inline-end: auto;
106
94
  }
107
95
  }
108
96
 
@@ -0,0 +1,78 @@
1
+ // Griffincss — Transforms
2
+ // Масштаб, поворот, сдвиг по осям и наведение с подъёмом.
3
+ //
4
+ // Суффиксов брейкпоинта и контейнера у модуля НЕТ и не будет. Довод и
5
+ // прецедент те же, что у логических отступов в _spacing.scss: карточка
6
+ // подскакивает под курсором одинаково на любой ширине окна, а девять
7
+ // вариантов на класс съели бы бюджет утилит целиком.
8
+ //
9
+ // Свойства раздельные — scale, rotate, translate, а не общий transform:
10
+ // три класса на одном элементе складываются, не затирая друг друга.
11
+
12
+ // Масштаб: ключ — проценты в имени класса, значение — множитель.
13
+ // Ступень 100 нужна, чтобы снять масштаб, доставшийся от другого класса.
14
+ $gr-scales: (95: 0.95, 100: 1, 105: 1.05, 110: 1.1) !default;
15
+
16
+ // Поворот в градусах. Каждая ступень даёт пару классов: .gr-rotate-6
17
+ // и .gr-rotate--6 — знак пишется в имени так же, как в значении.
18
+ $gr-rotations: (3, 6, 12, 45, 90) !default;
19
+
20
+ // Сдвиг: ключ — ступень шкалы отступов, значение — длина. Тоже парами,
21
+ // со знаком: подъём карточки — это .gr-translate-y--1.
22
+ $gr-translates: (1: 0.25rem, 2: 0.5rem) !default;
23
+
24
+ @each $gr-step, $gr-value in $gr-scales {
25
+ .gr-scale-#{$gr-step} { scale: $gr-value; }
26
+ }
27
+
28
+ @each $gr-deg in $gr-rotations {
29
+ .gr-rotate-#{$gr-deg} { rotate: #{$gr-deg}deg; }
30
+ .gr-rotate--#{$gr-deg} { rotate: -#{$gr-deg}deg; }
31
+ }
32
+
33
+ // Обе оси сдвига живут в одном свойстве translate, поэтому значение
34
+ // приходит настраиваемыми свойствами: иначе .gr-translate-x-2
35
+ // и .gr-translate-y-1 затёрли бы друг друга.
36
+ //
37
+ // Ноль по соседней оси — не украшение, а сброс наследования:
38
+ // настраиваемые свойства наследуются, и вложенный .gr-translate-y-1
39
+ // без сброса уехал бы вбок вслед за предком.
40
+ //
41
+ // Объявление повторяется в каждом классе, а не выносится в общий список
42
+ // селекторов. Это решено замером, а не вкусом: на тринадцати правилах
43
+ // общий список стоит 316 Б gzip против 300 Б у повтора — одинаковый
44
+ // хвост правила сжимается лучше, чем перечисление разных селекторов.
45
+ @mixin gr-shift($gr-x, $gr-y) {
46
+ --gr-tx: #{$gr-x};
47
+ --gr-ty: #{$gr-y};
48
+
49
+ translate: var(--gr-tx) var(--gr-ty);
50
+ }
51
+
52
+ @each $gr-step, $gr-value in $gr-translates {
53
+ .gr-translate-x-#{$gr-step} { @include gr-shift($gr-value, 0); }
54
+ .gr-translate-x--#{$gr-step} { @include gr-shift(-$gr-value, 0); }
55
+ .gr-translate-y-#{$gr-step} { @include gr-shift(0, $gr-value); }
56
+ .gr-translate-y--#{$gr-step} { @include gr-shift(0, -$gr-value); }
57
+ }
58
+
59
+ .gr-hover-lift { @include gr-shift(0, 0); }
60
+
61
+ // Наведение. Только под (hover: hover) — действующее правило проекта:
62
+ // на сенсорном экране :hover залипает после касания и снимается лишь
63
+ // касанием в другом месте.
64
+ //
65
+ // Подъём идёт через --gr-ty, а не через translate напрямую: карточка,
66
+ // уже сдвинутая по горизонтали, не теряет свой сдвиг под курсором.
67
+ // Переход объявлен здесь же — класс обязан работать в одиночку.
68
+ @media (hover: hover) {
69
+ .gr-hover-lift,
70
+ .gr-hover-grow { transition: translate var(--gr-transition), scale var(--gr-transition); }
71
+ .gr-hover-lift:hover { --gr-ty: -0.25rem; }
72
+ .gr-hover-grow:hover { scale: 1.03; }
73
+ }
74
+
75
+ @media (prefers-reduced-motion: reduce) {
76
+ .gr-hover-lift,
77
+ .gr-hover-grow { transition-duration: 0.01ms; }
78
+ }
@@ -17,7 +17,7 @@ $gr-text-sizes: (
17
17
  4xl: 2.25rem,
18
18
  5xl: 3rem,
19
19
  6xl: 3.75rem
20
- );
20
+ ) !default;
21
21
 
22
22
  @each $name, $size in $gr-text-sizes {
23
23
  .gr-text-#{$name} { font-size: $size; }
@@ -45,7 +45,7 @@ $gr-text-rel-steps: (
45
45
  xl: 4px,
46
46
  2xl: 6px,
47
47
  3xl: 8px
48
- );
48
+ ) !default;
49
49
 
50
50
  @each $gr-name, $gr-delta in $gr-text-rel-steps {
51
51
  .gr-text-rel-#{$gr-name} {
@@ -70,19 +70,17 @@ $gr-weights: (
70
70
  "bold": 700,
71
71
  "extrabold": 800,
72
72
  "black": 900
73
- );
73
+ ) !default;
74
74
 
75
75
  @each $name, $weight in $gr-weights {
76
76
  .gr-font-#{$name} { font-weight: $weight; }
77
77
  }
78
78
 
79
79
  // Text alignment
80
- // left/right буквальны и остаются такими: их выбирают, когда сторона
81
- // действительно нужна физическая. Разворот по направлению письма даёт
82
- // пара start/end — в LTR она совпадает с left/right, в RTL меняется местами.
83
- .gr-text-left { text-align: left; }
80
+ // Стороны — только логические: start — начало строки, end — конец,
81
+ // в RTL они меняются местами сами. Физические left/right удалены
82
+ // Этапом 36 вместе с остальными односторонними классами.
84
83
  .gr-text-center { text-align: center; }
85
- .gr-text-right { text-align: right; }
86
84
  .gr-text-justify { text-align: justify; }
87
85
  .gr-text-start { text-align: start; }
88
86
  .gr-text-end { text-align: end; }
@@ -99,7 +97,7 @@ $gr-leading: (
99
97
  normal: 1.5,
100
98
  relaxed: 1.625,
101
99
  loose: 2
102
- );
100
+ ) !default;
103
101
 
104
102
  @each $name, $value in $gr-leading {
105
103
  .gr-leading-#{$name} { line-height: $value; }
@@ -189,9 +187,7 @@ $gr-leading: (
189
187
  }
190
188
 
191
189
  // Text alignment responsive
192
- .gr-text-left#{$suffix} { text-align: left; }
193
190
  .gr-text-center#{$suffix} { text-align: center; }
194
- .gr-text-right#{$suffix} { text-align: right; }
195
191
  .gr-text-justify#{$suffix} { text-align: justify; }
196
192
  .gr-text-start#{$suffix} { text-align: start; }
197
193
  .gr-text-end#{$suffix} { text-align: end; }