PaniLara система сетки и контейнеров v4.loc

# ТЗ: система сетки и контейнеров v4.loc

Версия: 1.0 (май 2026)  

Статус: утверждённая реализация в `templates/good/css/greed.css`

## 1. Назначение и область

**Цель:** единая, предсказуемая вёрстка страниц на **CSS Grid** без JS для раскладки: контейнеры, адаптивные карточные сетки, кабинет (2 колонки), чат (3 колонки), узкая колонка для авторизации.

**Источник правды:**

| Ресурс | Путь |

|--------|------|

| Ядро сетки | `templates/good/css/greed.css` |

| Демо и описание в разметке | `grid.html` |

| Живые примеры | `cabinet.html`, `chat.html`, `login.html`, `schedule.html`, `menu.html` |

| Сборка бандла | `templates/good/css/build-master.ps1` → `master.css` / `master.prod.css` |


**Вне scope сетки (соседние слои):** шапка/меню (`menu.css`), формы (`forms.css`), чат (`chat.css`), карточки демо (`demo.css` — `.card`, `.aside-box`, `.footer-grid`).

---

## 2. Принципы проектирования

| Принцип | Реализация |

|--------|------------|

| Mobile-first | Базовая раскладка — одна колонка; расширение через `@media (min-width: …)` |

| Без JS для layout | Только CSS Grid + container queries |

| Минимальная DOM-обёртка | `main → section → container → контент` |

| Переполнение | У layout-утилит: `min-width: 0` на grid-родителе; у картинок: `max-width: 100%` |

| Высота колонок кабинета/чата | `align-items: stretch` (явно), **не** `align-items: start` у layout-родителя |

| Два типа брейкпоинтов | Viewport (`576/992/1200/1440px`) и layout-порог **`62rem`** (~992px) для кабинета/чата |

| Container queries | `.layout-sidebar`, `.col-narrow-center` — поведение от ширины **контейнера**, не viewport |

---

## 3. Глобальная структура страницы

```html

<body>

  <header class="site-header">…</header>

  <main>

    <section class="section">

      <div class="container">…</div>

    </section>

  </main>

  <footer class="site-footer">…</footer>

</body>

```

**`body`:** `display: flex; flex-direction: column; min-height: 100dvh` — футер прижат к низу.

**`main`:** `flex: 1` — растягивается между шапкой и футером.

**Секция:** класс `.section`, вертикальные отступы `padding-block: var(--space-7)` (48px).

---

## 4. Дизайн-токены (обязательные для сетки)

Определяются в `:root` файла `greed.css`:


```css

--container: 1440px;

--container-narrow: 800px;

--container-wide: 1440px;

--container-padding: clamp(12px, 2vw, 24px);


--space-1: 4px;

--space-2: 8px;

--space-3: 12px;

--space-4: 16px;

--space-5: 24px;

--space-6: 32px;

--space-7: 48px;


--layout-cab-aside: minmax(16rem, 18rem);

```


**Отступы между ячейками grid:** везде `gap: var(--space-4)` (16px), кроме плотных сеток с доп. `margin-top` у `.grid--five` / `.grid--six`.


---


## 5. Контейнеры


Общая формула ширины:


```css

width: min(100% - calc(var(--container-padding) * 2), 100%);

margin-inline: auto;

```


| Класс | `max-width` | Назначение |

|-------|-------------|------------|

| `.container` | `1440px` | Основной контент (шапка, секции, кабинет) |

| `.container-wide` | `1440px` | Алиас того же лимита |

| `.container-narrow` | `800px` | Long-form, узкий текст |

| `.container-fluid` | нет | На всю ширину viewport с теми же боковыми полями |


**Поведение:** контент центрируется; на широких мониторах не растягивается бесконечно. Fluid-полосы — отдельная секция с `.container-fluid` внутри `main` (см. демо на `grid.html`).


---


## 6. Карточные сетки (`.grid`)


Базовый класс:


```css

.grid {

  display: grid;

  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));

  gap: var(--space-4);

}

```


Число колонок **не задаётся брейкпоинтами** — подстраивается под ширину контейнера (`auto-fill` + `minmax`).


### Модификаторы


| Класс | `grid-template-columns` | Поведение |

|-------|-------------------------|-----------|

| `.grid-two` | `repeat(auto-fit, minmax(min(360px, 100%), 1fr))` | 2 колонки при достаточной ширине |

| `.grid-three` | `repeat(auto-fit, minmax(min(260px, 100%), 1fr))` | до 3 колонок |

| `.grid-four` | `repeat(auto-fit, minmax(min(220px, 100%), 1fr))` | до 4 колонок |

| `.grid--five` | базовая сетка; **с 1200px** → `repeat(5, minmax(0, 1fr))` | витрина каталога |

| `.grid--six` | базовая сетка; **с 1440px** → `repeat(6, minmax(0, 1fr))` | очень широкие экраны |


**Разметка:**


```html

<div class="grid grid-two">

  <article>…</article>

  <article>…</article>

</div>

```


Для 2–4 колонок используется **`auto-fit`** (колонки растягиваются, пустых треков нет).


---


## 7. Layout-утилиты


### 7.1 `.layout-pair-equal` — две колонки одной высоты


**Назначение:** сайдбар + основная область (`cabinet.html`, `schedule.html`, `menu.html`).


| Viewport | Колонки |

|----------|---------|

| &lt; 62rem | `1fr` (стек) |

| ≥ 62rem | `var(--layout-cab-aside) minmax(0, 1fr)` |


```css

.layout-pair-equal {

  display: grid;

  gap: var(--space-4);

  align-items: stretch;

  grid-template-columns: 1fr;

  min-width: 0;

}


@media (min-width: 62rem) {

  .layout-pair-equal {

    grid-template-columns: var(--layout-cab-aside) minmax(0, 1fr);

  }

}

```


**Разметка:**


```html

<div class="container">

  <div class="layout-pair-equal">

    <aside class="content-box">…</aside>

    <section class="content-box">…</section>

  </div>

</div>

```


**Правило:** высота ряда = максимуму содержимого; обе `.content-box` визуально одной высоты. Не ставить родителю `align-items: start`.


---


### 7.2 `.layout-trio-chat` — три колонки (профиль + список + диалог)


**Назначение:** `chat.html`.


| Viewport | Колонки |

|----------|---------|

| &lt; 62rem | одна колонка, порядок DOM сверху вниз |

| ≥ 62rem | `repeat(2, var(--layout-cab-aside)) minmax(0, 1fr)` |


Первые два трека **совпадают по ширине** с левой колонкой `.layout-pair-equal`.


```html

<div class="layout-trio-chat">

  <aside class="content-box">…</aside>

  <nav class="content-box chat-threads">…</nav>

  <section class="content-box chat">…</section>

</div>

```


Стили окна переписки — отдельно в `chat.css`.


---


### 7.3 `.layout-sidebar` — контент + сайдбар (container query)


```css

.layout-sidebar {

  display: grid;

  gap: var(--space-4);

  container-type: inline-size;

}


@container (min-width: 900px) {

  .layout-sidebar {

    grid-template-columns: minmax(0, 1fr) 320px;

  }

}

```


Переключение в 2 колонки когда **сам блок** ≥ 900px (не viewport). На мобильном сайдбар в потоке документа, не fixed.


---


### 7.4 `.col-narrow-center` — узкая колонка по центру (login)


```css

.col-narrow-center {

  width: min(100%, 420px);

  margin-inline: auto;

  container-type: inline-size;

  container-name: narrow-center;

}

```

**Паттерн:**


```html

<div class="container">

  <div class="col-narrow-center">

    <div class="form-tint-card">…</div>

  </div>

</div>

```

Вложенные карточки форм (`forms.css`):

```css

.form-tint-card {

  width: min(100%, 22rem);

  margin-inline: auto;

}

```


Без `margin-inline: auto` при `width: 100%` + `max-width` карточка визуально смещается влево на мобильном.


Container query `narrow-center` используется в формах (например, размер заголовка карточки от 24rem).


---


## 8. Вспомогательные блоки


| Класс | Файл | Назначение |

|-------|------|------------|

| `.content-box` | `greed.css` | Рамка + padding колонки кабинета/чата |

| `.aside-box` | `demo.css` | Демо-карточка с рамкой |

| `.prose` | `greed.css` | Типографика внутри контейнера |

| `.card` | `demo.css` | Карточка витрины внутри `.grid` |


`.content-box`:


```css

.content-box {

  padding: var(--space-4);

  border: 1px solid var(--border-color);

  border-radius: var(--radius-lg);

}

```


---


## 9. Шкала брейкпоинтов (viewport, mobile-first)


Утверждённая шкала (комментарий в `greed.css`, демо в `grid.html`):


| Минимальная ширина | Типичное использование |

|--------------------|-------------------------|

| **576px** | 2 колонки в `.footer-grid` (`demo.css`) |

| **992px** | Десктоп-шапка, горизонтальное меню (`menu.css`) |

| **1200px** | `.grid--five` → ровно 5 колонок |

| **1440px** | `.grid--six` → ровно 6 колонок |


**Отдельный layout-порог (не из этой четвёрки):**


| Порог | Где |

|-------|-----|

| **62rem** (~992px) | `.layout-pair-equal`, `.layout-trio-chat` |


**Container queries:**


| Контейнер | Условие | Эффект |

|-----------|---------|--------|

| `.layout-sidebar` | `min-width: 900px` | контент + sidebar 320px |

| `narrow-center` | `min-width: 24rem` | типографика в `.form-tint-card` (`forms.css`) |


---


## 10. Подключение стилей


**Минимум для страницы с сеткой:**


```html

<link rel="stylesheet" href="/templates/good/css/greed.css">

<link rel="stylesheet" href="/templates/good/css/demo.css">

```


**Продакшен-бандл:**


```powershell

powershell -NoProfile -File "templates/good/css/build-master.ps1" -ExcludeCalendar

```


Порядок в бандле: `greed.css` **первым** — токены и сетка не перебиваются.


---


## 11. Карта страниц → классы сетки


| Страница | Layout / сетка |

|----------|----------------|

| `grid.html` | Все паттерны (демо-референс) |

| `cabinet.html`, `schedule.html` | `.container` → `.layout-pair-equal` |

| `chat.html` | `.container` → `.layout-trio-chat` |

| `login.html` | `.container` → `.col-narrow-center` → `.form-tint-card` |

| `full.html` | `.grid.grid-two` + `.card` |

| Футер (все страницы) | `.container` → `.footer-grid` (2 col @576px, 4 col @1200px) |


---


## 12. Чеклист воспроизведения с нуля


1. Скопировать/воссоздать `:root` токены (`--container*`, `--space-*`, `--layout-cab-aside`, `--container-padding`).

2. Реализовать `box-sizing: border-box` глобально; `body` flex-column + `main { flex: 1 }`.

3. Контейнеры `.container` / `.container-narrow` / `.container-fluid` с формулой `min(100% - 2×padding, 100%)`.

4. `.section` с `padding-block: var(--space-7)`.

5. Базовый `.grid` + модификаторы `grid-two` … `grid-four`, `grid--five`, `grid--six` с media 1200/1440px.

6. `.layout-pair-equal` и `.layout-trio-chat` с порогом **62rem** и `align-items: stretch`.

7. `.layout-sidebar` с `container-type: inline-size` и `@container (min-width: 900px)`.

8. `.col-narrow-center` + container name `narrow-center`.

9. `.content-box` для колонок кабинета/чата.

10. Сверить с `grid.html` в браузере (320px, 576px, 992px, 1200px, 1440px).

11. Проверить `cabinet.html` и `chat.html` — совпадение ширины первых колонок.

12. Проверить `login.html` — карточка строго по центру на мобильном.


---


## 13. Антипаттерны


- `align-items: start` на `.layout-pair-equal` / `.layout-trio-chat` — колонки разной высоты по рамке.

- Фиксированный `min-height` в px/vh для выравнивания колонок кабинета.

- Дублирование DOM для mobile/desktop вместо одной сетки.

- `width: 100%` + `max-width` у вложенной карточки **без** `margin-inline: auto` — визуальный сдвиг влево.

- `<fieldset>` без `min-inline-size: 0` на узких формах — горизонтальный скролл.

- Подмена порога 62rem на 992px в layout-утилитах без согласования с дизайном (сейчас намеренно **rem**, не px viewport).


---


## 14. Критерии приёмки


- [ ] На ширине &lt; 62rem кабинет и чат — одна колонка, порядок как в DOM.

- [ ] На ≥ 62rem кабинет: aside ~16–18rem, main занимает остаток; колонки одной высоты.

- [ ] На ≥ 62rem чат: две узкие колонки равны ширине aside кабинета, третья — `1fr`.

- [ ] `.grid` / `grid-two`…`four` схлопываются без горизонтального скролла на 320px.

- [ ] `.grid--five` / `--six` дают ровно 5/6 колонок только на 1200+/1440+.

- [ ] `.col-narrow-center` и форма login центрированы на мобильном.

- [ ] `.layout-sidebar` переходит в 2 колонки при ширине родителя ≥ 900px, не viewport.

- [ ] Демо `grid.html` открывается и совпадает с описанием выше.


---


## Связанные файлы


```

templates/good/css/greed.css    — реализация

templates/good/css/demo.css     — .card, .aside-box, .footer-grid

templates/good/css/forms.css    — .form-tint-card, container narrow-center

templates/good/css/menu.css     — брейкпоинт 992px для шапки

grid.html                       — живая документация