/* ─── Layouts — ОБЩИЙ ФАЙЛ (overlay ↔ dashboard) ────────────────────── */
/* Правила макетов алерта, переехавшие из overlay.html:
     • .notification — доли макета (--split-*, --gap, --split-cap-*, --split-box)
       и grid-база (display/gap);
     • .layout-<x> — зоны-потолки (fit-content), явные ячейки media/text,
       overlay-бокс (--split-box), бюджет строк {message};
     • база .notification-media / .notification-text + типографика
       (.user-name / .message).
   Грузят ОБА хоста: боевой overlay и dashboard — плитки макета
   и превью анимаций рисуются ТЕМИ ЖЕ селекторами (честное превью,
   вместо старых SVG-иконок public/img/layouts_*.svg).
   Хост задаёт: единицу сцены --u (overlay: calc(100vh/1080); превью —
   своя маленькая), размеры карточки, opacity/анимации (animations.css)
   и контент (.notification-media с img/video в overlay, плейсхолдеры
   в превью). DOM карточки: .notification > .notification-media +
   .notification-text (порядок media → text — ячейки заданы явно). */

.notification {
  /* ═══ ДОЛИ МАКЕТА — тесты разделителя в ОДНОМ месте ═══
     Доли — ЧИСЛА: пропорции зон = МАКСИМАЛЬНЫЙ контент-блока.
       Классика ¼ + ¾: --split-small: 1, --split-big: 3 (по умолчанию).
       Тест ⅓ + ⅔:    --split-big: 2 — потолки зон и бокс overlay
                        (--split-box) пересчитаются сами, больше ничего
                        не править.
     Потолки (fit-content в .layout-* ниже): зона = доля × (карточка −
     gap); контент меньше доли → зона СЖИМАЕТСЯ под контент, блоки идут
     вплотную (gap 24·u) и центрируются ГРУППОЙ [медиа][gap][текст], а не
     каждый внутри своего отсека. Контент больше доли → зона зажата долей. */
  --split-small: 1;      /* малая доля: колонка медиа в side, потолок строки текста в top/bottom */
  --split-big:   3;      /* большая доля: строка медиа в top/bottom, колонка текста в side */
  --gap: calc(24 * var(--u, 1px));  /* зазор медиа↔текст (в overlay не участвует) */
  --split-cap-big:   calc((100% - var(--gap)) * var(--split-big) / (var(--split-big) + var(--split-small)));
  --split-cap-small: calc((100% - var(--gap)) * var(--split-small) / (var(--split-big) + var(--split-small)));
  --split-box: calc(var(--split-big) / (var(--split-big) + var(--split-small)) * 100%);  /* overlay: бокс = большая доля */
  display: grid;
  gap: var(--gap);
}

/* ─── Layout variants (per-reward `layout`) ────────────────────────── */
/* Макет делится на зоны-МАКСИМУМЫ (доли — числа --split-* в
   .notification, тест ¼/¾ ↔ ⅓/⅔ правится в одном месте):
     media-top    — большая строка медиа сверху, строка текста снизу;
     media-bottom — строка текста сверху, большая строка медиа снизу;
     side-left    — малая колонка медиа слева, большая колонка текста справа;
     side-right   — большая колонка текста слева, малая колонка медиа справа;
     overlay      — оба в центральном боксе (--split-box), текст поверх медиа.
   Строки/колонки контентные с потолком-долей (fit-content): контент
   меньше доли → зона сжимается, блоки идут вплотную с gap и ГРУППА
   [медиа][gap][текст] центрируется в макете (align/justify-content:
   center), а не каждый блок внутри своего отсека; контент больше доли →
   зона зажата долей (обрезка «...»). Картинка вписывается в зону целиком
   (fit считает JS). Выбирается в dashboard → rewardConfig.layout →
   .layout-<x>. Вход — пресет .anim-<x> из animations.css (на
   .notification), выход — общий .fade-out; content-элементы
   наследуют motion через opacity/transform родителя. */

.notification.layout-media-top    { grid-template-rows: fit-content(var(--split-cap-big)) fit-content(var(--split-cap-small)); align-content: center; }
.notification.layout-media-bottom { grid-template-rows: fit-content(var(--split-cap-small)) fit-content(var(--split-cap-big)); align-content: center; }
.notification.layout-side-left    { grid-template-columns: fit-content(var(--split-cap-small)) fit-content(var(--split-cap-big)); justify-content: center; }
.notification.layout-side-right   { grid-template-columns: fit-content(var(--split-cap-big)) fit-content(var(--split-cap-small)); justify-content: center; }

/* Явное размещение ячеек (DOM-порядок: media → text) */
.notification.layout-media-top    .notification-media { grid-area: 1 / 1; }
.notification.layout-media-top    .notification-text  { grid-area: 2 / 1; }
.notification.layout-media-bottom .notification-text  { grid-area: 1 / 1; }
.notification.layout-media-bottom .notification-media { grid-area: 2 / 1; }
.notification.layout-side-left    .notification-media { grid-area: 1 / 1; }
.notification.layout-side-left    .notification-text  { grid-area: 1 / 2; }
.notification.layout-side-right   .notification-text  { grid-area: 1 / 1; }
.notification.layout-side-right   .notification-media { grid-area: 1 / 2; }

/* overlay: оба элемента в одной ячейке (карточка = макет − поле),
   бокс = --split-box (¾×¾ по умолчанию) по центру — задаётся ниже. */
.notification.layout-overlay                     { grid-template: minmax(0, 1fr) / minmax(0, 1fr); }
.notification.layout-overlay .notification-media,
.notification.layout-overlay .notification-text  { grid-area: 1 / 1; }

.notification.layout-overlay .notification-media {
  position: relative; /* stacking-context для media → текст (z-index: 1) ровно поверх неё */
  z-index: 0;
  place-self: center;
  width: var(--split-box);   /* ¾×¾ при долях 3+1 (600×450 при source 800×600) */
  height: var(--split-box);
}

/* Текст overlay — поверх медиа (place-self из базы): ширина во всю
   ширину макета, как в media-top/media-bottom (без потолка бокса —
   fit-content дотягивается до карточки); по вертикали ограничен
   боксом (--split-box). */
.notification.layout-overlay .notification-text {
  z-index: 1;
  max-width: 100%;
  max-height: var(--split-box);
}

/* ─── Media ──────────────────────────────────────────────────── */
/* Медиа-группа: контейнер grid-зоны (растягивается), элемент внутри
   центрируется и имеет fit-размер (считает JS, см. createNotificationMedia).
   Всегда ОДИН элемент (на уведомление — один media-ассет), поэтому
   внутреннего gap тут нет. Присутствует только если есть media-ассет. */
.notification .notification-media {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* ─── Text (опциональный content-элемент Notification) ─────────── */
/* Плашка: по контенту, отцентрована в своей grid-зоне, ограничена ею
   (max 100%, overflow hidden — ничего не вылезает за края зоны и за
   рамки макета). min-width — не уже 300·u, но и не шире зоны.
   pointer-events/opacity не задаём: наследуются от .notification. */
.notification .notification-text {
  place-self: center;
  width: fit-content;
  max-width: 100%;
  max-height: 100%;
  min-width: min(calc(300 * var(--u, 1px)), 100%);
  overflow: hidden;
  padding: calc(16 * var(--u, 1px)) calc(32 * var(--u, 1px));
  border-radius: calc(12 * var(--u, 1px));
  text-align: center;
}

.notification .notification-text .user-name {
  font-weight: 700;
  font-size: calc(20 * var(--u, 1px));
  margin-bottom: calc(4 * var(--u, 1px));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;   /* длинный ник — в одну строку с «...» */
}

.notification .notification-text .message {
  font-size: calc(14 * var(--u, 1px));
  opacity: 0.8;
  margin-top: calc(4 * var(--u, 1px));
  font-style: italic;
  overflow-wrap: anywhere;   /* длинные слова не рвут границы зоны */
  /* Многострочная обрезка «...» в пределах зоны */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  -webkit-line-clamp: var(--msg-lines, 10);
}

/* Бюджет строк {message} — верхний предел для fitMsgClamp (JS считает
   фактический clamp под реальную высоту плочки, чтобы низ обрезался
   «...», а не плоско): top/bottom — дефолт 10, side/overlay — 12. */
.notification.layout-side-left    .notification-text,
.notification.layout-side-right   .notification-text,
.notification.layout-overlay      .notification-text { --msg-lines: 12; }

