griffincss-utils 0.16.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 ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "griffincss-utils",
3
+ "version": "0.16.0",
4
+ "description": "Griffincss Utils — утилитарные классы: отступы, типографика, цвета, видимость, скругления",
5
+ "homepage": "https://gitverse.ru/BarneyScott/GriffinCSS",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://gitverse.ru/BarneyScott/GriffinCSS.git",
9
+ "directory": "packages/utils"
10
+ },
11
+ "bugs": {
12
+ "url": "https://gitverse.ru/BarneyScott/GriffinCSS/issues"
13
+ },
14
+ "author": "Лазарев Михаил Юрьевич <bersi82@gmail.com>",
15
+ "license": "MIT",
16
+ "main": "dist/griffincss-utils.css",
17
+ "style": "dist/griffincss-utils.css",
18
+ "sass": "scss/griffincss-utils.scss",
19
+ "exports": {
20
+ ".": "./dist/griffincss-utils.css",
21
+ "./js": "./dist/griffincss-utils.js",
22
+ "./scoped": "./dist/griffincss-utils-scoped.css",
23
+ "./scss": "./scss/griffincss-utils.scss",
24
+ "./scss/*": "./scss/*",
25
+ "./dist/*": "./dist/*",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist/",
30
+ "scss/",
31
+ "src/"
32
+ ],
33
+ "peerDependencies": {
34
+ "griffincss-core": "^0.16.0"
35
+ },
36
+ "keywords": [
37
+ "css",
38
+ "scss",
39
+ "sass",
40
+ "utilities",
41
+ "spacing",
42
+ "typography",
43
+ "griffincss"
44
+ ],
45
+ "scripts": {
46
+ "build": "npm run build:css && npm run build:scoped && npm run build:js",
47
+ "build:css": "sass scss/griffincss-utils.scss dist/griffincss-utils.css --load-path=../../node_modules --style=compressed --no-source-map",
48
+ "build:scoped": "sass scss/griffincss-utils-scoped.scss dist/griffincss-utils-scoped.css --load-path=../../node_modules --style=compressed --no-source-map",
49
+ "build:js": "terser src/griffincss-utils.js -c passes=3 -m --comments false --format \"preamble='/*! Griffincss Utils | MIT | https://gitverse.ru/BarneyScott/GriffinCSS */'\" --source-map \"url='griffincss-utils.js.map'\" -o dist/griffincss-utils.js"
50
+ }
51
+ }
@@ -0,0 +1,82 @@
1
+ // Griffincss — Transitions & Animation
2
+ // Плавные переходы, их длительность и один-единственный keyframe.
3
+ //
4
+ // Полноценной библиотеки анимаций здесь нет и не планируется: fade, slide
5
+ // и pulse — задача уровня приложения, а не фреймворка раскладки. Оставлен
6
+ // gr-spin: индикатор загрузки нужен практически в каждом проекте.
7
+ //
8
+ // Всё содержимое модуля выключается при prefers-reduced-motion: reduce —
9
+ // движение не убирается совсем (иначе ломаются состояния, завязанные
10
+ // на конец перехода), а сжимается до неразличимого.
11
+
12
+ .gr-transition {
13
+ transition: all var(--gr-transition);
14
+ }
15
+
16
+ .gr-transition-colors {
17
+ transition:
18
+ color var(--gr-transition),
19
+ background-color var(--gr-transition),
20
+ border-color var(--gr-transition),
21
+ fill var(--gr-transition),
22
+ stroke var(--gr-transition);
23
+ }
24
+
25
+ .gr-transition-opacity {
26
+ transition: opacity var(--gr-transition);
27
+ }
28
+
29
+ .gr-transition-transform {
30
+ transition: transform var(--gr-transition);
31
+ }
32
+
33
+ .gr-transition-shadow {
34
+ transition: box-shadow var(--gr-transition);
35
+ }
36
+
37
+ .gr-transition-none {
38
+ transition: none;
39
+ }
40
+
41
+ // Длительность. Перебивает часть токена --gr-transition, функция сглаживания
42
+ // при этом сохраняется — она приходит из того же сокращённого свойства выше.
43
+ @each $gr-ms in (75, 100, 150, 200, 300, 500, 700, 1000) {
44
+ .gr-duration-#{$gr-ms} {
45
+ transition-duration: #{$gr-ms}ms;
46
+ }
47
+ }
48
+
49
+ .gr-animate-spin {
50
+ animation: gr-spin 1s linear infinite;
51
+ }
52
+
53
+ @media (prefers-reduced-motion: reduce) {
54
+ .gr-transition,
55
+ .gr-transition-colors,
56
+ .gr-transition-opacity,
57
+ .gr-transition-transform,
58
+ .gr-transition-shadow {
59
+ transition-duration: 0.01ms;
60
+ }
61
+
62
+ .gr-animate-spin {
63
+ animation-duration: 3s;
64
+ }
65
+ }
66
+
67
+ // Печать. Переход на бумаге не значит ничего, а вращающийся индикатор
68
+ // печатается замершим в случайном положении. Блок стоит последним в модуле:
69
+ // специфичность у него та же, что у правил выше, и решает порядок.
70
+ @media print {
71
+ .gr-transition,
72
+ .gr-transition-colors,
73
+ .gr-transition-opacity,
74
+ .gr-transition-transform,
75
+ .gr-transition-shadow {
76
+ transition: none;
77
+ }
78
+
79
+ .gr-animate-spin {
80
+ animation: none;
81
+ }
82
+ }
@@ -0,0 +1,65 @@
1
+ // Griffincss — Border Radius Cascade
2
+ // Дочерние блоки автоматически получают меньший радиус,
3
+ // пропорционально зазору от края родителя.
4
+ // child_radius = max(0, --gr-r - --gr-p)
5
+ //
6
+ // --gr-r: border-radius контейнера (по умолчанию 0)
7
+ // --gr-p: зазор между краем контейнера и ребёнком; из него выводится padding,
8
+ // поэтому JS для первого уровня не нужен вовсе
9
+ //
10
+ // Зазор один на все стороны: асимметричный padding (.gr-px-*, .gr-py-*
11
+ // и односторонние) каскадом не поддержан — у него нет одного значения,
12
+ // от которого считать радиус ребёнка.
13
+ //
14
+ // Обе переменные зарегистрированы через @property как ненаследуемые
15
+ // (packages/core/scss/_tokens.scss): значение уровня объявляется на нём
16
+ // самом, а вниз уходит публикация --gr-r-down и --gr-r-gap.
17
+ //
18
+ // <div class="gr-radius gr-radius-8" style="--gr-p: 16px">…</div>
19
+ //
20
+ // Вложенный .gr-radius без своего --gr-r даёт квадрат: радиус предка он
21
+ // не копирует. Многоуровневый каскад без ручных значений достраивает
22
+ // рантайм griffincss-utils.js.
23
+
24
+ // Каскадный контейнер: зазор — источник, padding — следствие
25
+ .gr-radius {
26
+ padding: var(--gr-p);
27
+ border-radius: var(--gr-r);
28
+
29
+ // Публикация вниз. Дети читают эти две, а не --gr-r/--gr-p: те
30
+ // намеренно не наследуются, иначе вложенный контейнер копировал бы
31
+ // радиус предка. Цикла тут нет — читаем одно имя, пишем другое.
32
+ --gr-r-down: var(--gr-r);
33
+ --gr-r-gap: var(--gr-p);
34
+ }
35
+
36
+ .gr-radius > :not(.gr-radius) {
37
+ border-radius: max(0px, calc(var(--gr-r-down, 0px) - var(--gr-r-gap, 0px)));
38
+ }
39
+
40
+ // Предопределённые радиусы (шаг 0.25rem, от 0 до 16 = 4rem)
41
+ $gr-radius-base: 0.25rem;
42
+ $gr-radius-max: 16;
43
+
44
+ @for $i from 0 through $gr-radius-max {
45
+ $val: $i * $gr-radius-base;
46
+
47
+ .gr-radius-#{$i} {
48
+ --gr-r: #{$val};
49
+
50
+ border-radius: #{$val};
51
+ }
52
+ }
53
+
54
+ // Pill / полностью скруглённый
55
+ .gr-radius-full {
56
+ --gr-r: 9999px;
57
+
58
+ border-radius: 9999px;
59
+ }
60
+
61
+ // Адаптивных вариантов у радиусов нет: скругление, меняющееся по ширине окна, —
62
+ // редкий сценарий, а полная сетка -sm/-md/-lg/-xl стоила бы 68 лишних классов.
63
+ // Когда он всё же нужен, --gr-r переопределяется своим медиа-запросом:
64
+ //
65
+ // @media (width >= 768px) { .card { --gr-r: 1rem; } }
@@ -0,0 +1,93 @@
1
+ // Griffincss — Borders
2
+ // Ширина, стиль и стороны границы.
3
+ //
4
+ // Разделение обязанностей внутри пакета:
5
+ // _borders.scss — сама граница (width / style / side);
6
+ // _colors.scss — цвет (.gr-border-primary и прочие);
7
+ // _border-radius.scss — скругления с каскадом по вложенности.
8
+ //
9
+ // Ширина по умолчанию — токен --gr-border-width: режим для слабовидящих
10
+ // поднимает её до 2px, не переписывая ни одного правила. Явные .gr-border-2
11
+ // и старше остаются литеральными: их ширину выбрал автор разметки.
12
+ //
13
+ // Каждый класс ширины самодостаточен — задаёт и стиль, и цвет по умолчанию,
14
+ // поэтому .gr-border-2 виден сам по себе. Классы цвета подключаются в точке
15
+ // входа после этого модуля, так что .gr-border-2.gr-border-danger даёт
16
+ // красную границу в 2px: побеждает более поздний border-color.
17
+
18
+ // Ширина. Ноль вынесен отдельно: там сбрасывается вся граница целиком.
19
+ .gr-border-0 {
20
+ border: 0;
21
+ }
22
+
23
+ .gr-border {
24
+ border: var(--gr-border-width, 1px) solid var(--gr-color-border);
25
+ }
26
+
27
+ @each $gr-width in (2, 4, 8) {
28
+ .gr-border-#{$gr-width} {
29
+ border: #{$gr-width}px solid var(--gr-color-border);
30
+ }
31
+ }
32
+
33
+ // Стороны. Физические t/r/b/l остаются буквальными, логические s/e идут
34
+ // рядом: в LTR они совпадают с l/r, в RTL меняются местами сами.
35
+ $gr-border-sides: (
36
+ t: top,
37
+ r: right,
38
+ b: bottom,
39
+ l: left,
40
+ s: inline-start,
41
+ e: inline-end
42
+ );
43
+
44
+ // Ширина у стороны задаётся своим классом, а не парой .gr-border-l + .gr-border-4:
45
+ // класс ширины пишет сокращённое свойство border и сбрасывает вместе с ним все
46
+ // четыре стороны, так что «толстая граница слева» такой парой не получается.
47
+ @each $gr-key, $gr-side in $gr-border-sides {
48
+ .gr-border-#{$gr-key} {
49
+ border-#{$gr-side}: var(--gr-border-width, 1px) solid var(--gr-color-border);
50
+ }
51
+
52
+ .gr-border-#{$gr-key}-0 {
53
+ border-#{$gr-side}: 0;
54
+ }
55
+
56
+ @each $gr-width in (2, 4, 8) {
57
+ .gr-border-#{$gr-key}-#{$gr-width} {
58
+ border-#{$gr-side}: #{$gr-width}px solid var(--gr-color-border);
59
+ }
60
+ }
61
+ }
62
+
63
+ // Оси — граница только по бокам либо только сверху и снизу.
64
+ // Записаны логическими сокращениями: у оси обе стороны получают одно
65
+ // и то же значение, поэтому направление письма результата не меняет,
66
+ // а вместо двух объявлений выводится одно.
67
+ $gr-border-axes: (
68
+ x: inline,
69
+ y: block
70
+ );
71
+
72
+ @each $gr-key, $gr-axis in $gr-border-axes {
73
+ .gr-border-#{$gr-key} {
74
+ border-#{$gr-axis}: var(--gr-border-width, 1px) solid var(--gr-color-border);
75
+ }
76
+
77
+ .gr-border-#{$gr-key}-0 {
78
+ border-#{$gr-axis}: 0;
79
+ }
80
+
81
+ @each $gr-width in (2, 4, 8) {
82
+ .gr-border-#{$gr-key}-#{$gr-width} {
83
+ border-#{$gr-axis}: #{$gr-width}px solid var(--gr-color-border);
84
+ }
85
+ }
86
+ }
87
+
88
+ // Стиль. Применяется поверх класса ширины: .gr-border .gr-border-dashed.
89
+ @each $gr-style in (solid, dashed, dotted, double, none) {
90
+ .gr-border-#{$gr-style} {
91
+ border-style: $gr-style;
92
+ }
93
+ }
@@ -0,0 +1,88 @@
1
+ // Griffincss — Color Utilities
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
+ );
41
+
42
+ // Background utilities
43
+ @each $name, $hsl in $gr-grays {
44
+ .gr-bg-#{$name} { background-color: hsl(#{$hsl}); }
45
+ }
46
+
47
+ @each $name, $hsl in $gr-accents {
48
+ .gr-bg-#{$name} { background-color: hsl(#{$hsl}); }
49
+ }
50
+
51
+ // Text color utilities
52
+ @each $name, $hsl in $gr-grays {
53
+ .gr-text-#{$name} { color: hsl(#{$hsl}); }
54
+ }
55
+
56
+ @each $name, $hsl in $gr-accents {
57
+ .gr-text-#{$name} { color: hsl(#{$hsl}); }
58
+ }
59
+
60
+ // Border color utilities
61
+ @each $name, $hsl in $gr-grays {
62
+ .gr-border-#{$name} { border-color: hsl(#{$hsl}); }
63
+ }
64
+
65
+ @each $name, $hsl in $gr-accents {
66
+ .gr-border-#{$name} { border-color: hsl(#{$hsl}); }
67
+ }
68
+
69
+ // Семантические цвета — единственные, которые переключаются темой.
70
+ // Литеральные классы выше (.gr-bg-white, .gr-text-gray-900) остаются
71
+ // буквальными по контракту: белое обязано быть белым в любой теме.
72
+ // Разметку, которая должна жить по теме, пишут на этих классах.
73
+ .gr-bg-page { background-color: var(--gr-color-bg); }
74
+ .gr-bg-surface { background-color: var(--gr-color-surface); }
75
+ .gr-bg-raised { background-color: var(--gr-color-surface-raised); }
76
+ .gr-bg-sunken { background-color: var(--gr-color-surface-sunken); }
77
+ .gr-bg-accent { background-color: var(--gr-color-accent); }
78
+
79
+ .gr-text-ink { color: var(--gr-color-text); }
80
+ .gr-text-ink-secondary { color: var(--gr-color-text-secondary); }
81
+ .gr-text-ink-muted { color: var(--gr-color-text-muted); }
82
+ .gr-text-ink-disabled { color: var(--gr-color-text-disabled); }
83
+ .gr-text-accent { color: var(--gr-color-accent); }
84
+ .gr-text-on-accent { color: var(--gr-color-on-accent); }
85
+ .gr-text-link { color: var(--gr-color-link); }
86
+
87
+ .gr-border-subtle { border-color: var(--gr-color-border); }
88
+ .gr-border-strong { border-color: var(--gr-color-border-strong); }
@@ -0,0 +1,28 @@
1
+ // Griffincss — Effects
2
+ // Прозрачность, вписывание медиа и пропорции блока.
3
+
4
+ // Прозрачность
5
+ $gr-opacities: (0: 0, 25: 0.25, 50: 0.5, 75: 0.75, 100: 1);
6
+
7
+ @each $gr-step, $gr-value in $gr-opacities {
8
+ .gr-opacity-#{$gr-step} { opacity: $gr-value; }
9
+ }
10
+
11
+ // Вписывание картинки или видео в отведённую рамку.
12
+ // Ресет уже задаёт медиа display: block и max-width: 100%, поэтому здесь
13
+ // остаётся только кадрирование.
14
+ @each $gr-fit in (cover, contain, fill, none, scale-down) {
15
+ .gr-object-#{$gr-fit} { object-fit: $gr-fit; }
16
+ }
17
+
18
+ // Точка привязки кадра: у портретов обрезать снизу, а не по центру.
19
+ @each $gr-pos in (center, top, right, bottom, left) {
20
+ .gr-object-pos-#{$gr-pos} { object-position: $gr-pos; }
21
+ }
22
+
23
+ // Пропорции блока
24
+ .gr-aspect-square { aspect-ratio: 1 / 1; }
25
+ .gr-aspect-video { aspect-ratio: 16 / 9; }
26
+ .gr-aspect-wide { aspect-ratio: 21 / 9; }
27
+ .gr-aspect-portrait { aspect-ratio: 3 / 4; }
28
+ .gr-aspect-auto { aspect-ratio: auto; }
@@ -0,0 +1,26 @@
1
+ // Griffincss — Interactivity
2
+ // Курсор, приём событий указателя, выделение текста, прокрутка.
3
+
4
+ $gr-cursors: (pointer, default, text, move, grab, grabbing, wait, progress, help, not-allowed);
5
+
6
+ @each $gr-value in $gr-cursors {
7
+ .gr-cursor-#{$gr-value} { cursor: $gr-value; }
8
+ }
9
+
10
+ .gr-pointer-events-none { pointer-events: none; }
11
+ .gr-pointer-events-auto { pointer-events: auto; }
12
+
13
+ // Имя утилиты повторяет имя свойства — user-select, а не select: короткое
14
+ // .gr-select занято элементом формы в griffincss-ui, и один корень на два
15
+ // разных смысла вёрстальщику не помогает.
16
+ @each $gr-value in (none, all, text, auto) {
17
+ .gr-user-select-#{$gr-value} { user-select: $gr-value; }
18
+ }
19
+
20
+ // Плавная прокрутка — только для тех, кто не просил уменьшить анимацию.
21
+ // Класс объявлен всегда, иначе .gr-scroll-auto не смог бы его перебить.
22
+ .gr-scroll-auto { scroll-behavior: auto; }
23
+
24
+ @media (prefers-reduced-motion: no-preference) {
25
+ .gr-scroll-smooth { scroll-behavior: smooth; }
26
+ }
@@ -0,0 +1,11 @@
1
+ // Griffincss — Keyframes
2
+ // Отдельный файл, а не часть _animations.scss: внутри @scope правила
3
+ // @keyframes недействительны, поэтому в scoped-сборке они подключаются
4
+ // вне области видимости. Имена префиксованы gr-, чтобы не столкнуться
5
+ // с анимациями проекта.
6
+
7
+ @keyframes gr-spin {
8
+ to {
9
+ transform: rotate(360deg);
10
+ }
11
+ }
@@ -0,0 +1,60 @@
1
+ // Griffincss — Position
2
+ // Схема позиционирования, привязка к краям и порядок наложения.
3
+ //
4
+ // Адаптивные варианты есть только у самой схемы: «липнет на десктопе,
5
+ // обычный блок на мобильном» — рабочий сценарий, а вот z-index, меняющийся
6
+ // по ширине окна, за всё время не понадобился ни разу.
7
+
8
+ @use 'griffincss-core/scss/breakpoints' as bp;
9
+
10
+ $gr-positions: (static, relative, absolute, fixed, sticky);
11
+
12
+ @mixin gr-position-scale($suffix: '') {
13
+ @each $gr-value in $gr-positions {
14
+ .gr-#{$gr-value}#{$suffix} { position: $gr-value; }
15
+ }
16
+ }
17
+
18
+ @include gr-position-scale;
19
+
20
+ // Привязка к краям
21
+ .gr-inset-0 { inset: 0; }
22
+ .gr-inset-auto { inset: auto; }
23
+
24
+ // Оси записаны логическими свойствами: обе стороны у них равны, поэтому
25
+ // направление письма результата не меняет, а объявлений вдвое меньше.
26
+ .gr-inset-x-0 {
27
+ inset-inline: 0;
28
+ }
29
+
30
+ .gr-inset-y-0 {
31
+ inset-block: 0;
32
+ }
33
+
34
+ @each $gr-side in (top, right, bottom, left) {
35
+ .gr-#{$gr-side}-0 { #{$gr-side}: 0; }
36
+ .gr-#{$gr-side}-auto { #{$gr-side}: auto; }
37
+ }
38
+
39
+ // Односторонние left/right остаются физическими намеренно: кнопка «закрыть»
40
+ // в углу окна обязана держаться угла, а не начала строки. Привязку к строке
41
+ // даёт логическая пара start/end — в LTR она совпадает с left/right.
42
+ @each $gr-key, $gr-side in (start: inset-inline-start, end: inset-inline-end) {
43
+ .gr-#{$gr-key}-0 { #{$gr-side}: 0; }
44
+ .gr-#{$gr-key}-auto { #{$gr-side}: auto; }
45
+ }
46
+
47
+ // Порядок наложения. Шаг 10 оставляет место для своих значений между
48
+ // ступенями — их можно вписать, не трогая библиотеку.
49
+ @each $gr-z in (0, 10, 20, 30, 40, 50) {
50
+ .gr-z-#{$gr-z} { z-index: $gr-z; }
51
+ }
52
+
53
+ .gr-z-auto { z-index: auto; }
54
+
55
+ // Адаптивные варианты
56
+ @each $bp-name, $bp-value in bp.$gr-breakpoints {
57
+ @media (width >= $bp-value) {
58
+ @include gr-position-scale('-#{$bp-name}');
59
+ }
60
+ }
@@ -0,0 +1,19 @@
1
+ // Griffincss — Shadows
2
+ // Тени для передачи глубины интерфейса.
3
+ //
4
+ // Значения живут в токенах --gr-shadow-* (_tokens.scss ядра), поэтому
5
+ // переопределяются пользователем без пересборки SCSS. Цвет вынесен
6
+ // в отдельный --gr-shadow-color в формате HSL-компонент: в тёмной теме
7
+ // (Этап 5) меняется одна переменная, а не шесть готовых теней.
8
+
9
+ $gr-shadows: (xs, sm, md, lg, xl, 2xl, inner);
10
+
11
+ @each $gr-name in $gr-shadows {
12
+ .gr-shadow-#{$gr-name} {
13
+ box-shadow: var(--gr-shadow-#{$gr-name});
14
+ }
15
+ }
16
+
17
+ .gr-shadow-none {
18
+ box-shadow: none;
19
+ }
@@ -0,0 +1,75 @@
1
+ // Griffincss — Sizing
2
+ // Ширина, высота и ограничители min/max.
3
+ //
4
+ // Дробные ширины записываются в разметке как есть: class="gr-w-1/2".
5
+ // Слэш экранируется только в CSS-селекторе — писать его в HTML не нужно.
6
+ //
7
+ // Единицы вьюпорта — малые (svw/svh): они не учитывают исчезающие панели
8
+ // мобильных браузеров, поэтому блок не «прыгает» при прокрутке, а .gr-w-screen
9
+ // не вызывает горизонтальную прокрутку из-за ширины полосы прокрутки.
10
+
11
+ @use 'griffincss-core/scss/breakpoints' as bp;
12
+ @use 'griffincss-core/scss/container-mixins' as cq;
13
+
14
+ $gr-widths: (
15
+ full: 100%,
16
+ screen: 100svw,
17
+ auto: auto,
18
+ fit: fit-content,
19
+ min: min-content,
20
+ max: max-content,
21
+ "1\\/2": 50%,
22
+ "1\\/3": 33.3333%,
23
+ "2\\/3": 66.6667%,
24
+ "1\\/4": 25%,
25
+ "3\\/4": 75%
26
+ ) !default;
27
+
28
+ // Высот меньше: 100% у блока без заданной высоты родителя не значит ничего,
29
+ // поэтому дробных вариантов здесь нет — их роль играет grid.
30
+ $gr-heights: (
31
+ full: 100%,
32
+ screen: 100svh,
33
+ auto: auto,
34
+ fit: fit-content
35
+ ) !default;
36
+
37
+ @mixin gr-sizing-scale($suffix: '') {
38
+ @each $gr-name, $gr-value in $gr-widths {
39
+ .gr-w-#{$gr-name}#{$suffix} { width: $gr-value; }
40
+ }
41
+
42
+ @each $gr-name, $gr-value in $gr-heights {
43
+ .gr-h-#{$gr-name}#{$suffix} { height: $gr-value; }
44
+ }
45
+ }
46
+
47
+ @include gr-sizing-scale;
48
+
49
+ // Ограничители. Адаптивных вариантов не имеют: min/max по смыслу задают
50
+ // рамку, одинаковую на всех ширинах, — меняют её обычно сами width/height.
51
+ .gr-min-w-0 { min-width: 0; }
52
+ .gr-min-w-full { min-width: 100%; }
53
+ .gr-min-h-0 { min-height: 0; }
54
+ .gr-min-h-full { min-height: 100%; }
55
+ .gr-min-h-screen { min-height: 100svh; }
56
+
57
+ .gr-max-w-none { max-width: none; }
58
+ .gr-max-w-full { max-width: 100%; }
59
+ .gr-max-w-page { max-width: var(--gr-max-width); }
60
+ .gr-max-h-full { max-height: 100%; }
61
+ .gr-max-h-screen { max-height: 100svh; }
62
+
63
+ // Адаптивные варианты — только у width и height
64
+ @each $bp-name, $bp-value in bp.$gr-breakpoints {
65
+ @media (width >= $bp-value) {
66
+ @include gr-sizing-scale('-#{$bp-name}');
67
+ }
68
+ }
69
+
70
+ // Контейнерные варианты — от ширины ближайшего предка с .gr-cq
71
+ @each $bp-name, $bp-value in bp.$gr-breakpoints {
72
+ @include cq.gr-container-media($bp-name) {
73
+ @include gr-sizing-scale('-c#{$bp-name}');
74
+ }
75
+ }