/* ══════════════════════════════════════════════════════════════════════════
   UI-KIT — спільні компоненти, народжені в Studio
   ══════════════════════════════════════════════════════════════════════════

   Studio переробили за ергономікою Higgsfield Marketing Studio, і там
   з'явились три речі, яких не було більше ніде в застосунку. Поки вони жили
   всередині одного розділу, решта вкладок лишалась у старому шарі — тобто
   продукт розмовляв двома мовами. Тут вони винесені в спільні класи `.ui-*`.

   Виміряно з живих сторінок higgsfield.ai (не на око):
     · стрічка матеріалів — щільна сітка плиток ФІКСОВАНОЇ пропорції, медіа
       заповнює плитку повністю, тип позначає дрібний гліф у кутку. Жодних
       підписів під плиткою в самій стрічці: контент і є підпис;
     · композер — ОДИН контейнер: рядок тексту, під ним рядок чипів-налаштувань,
       праворуч єдина акцентна кнопка на всю висоту;
     · картка сутності — піктограма в кутку, бейдж навпроти, назва, один рядок
       пояснення. Ніякої рамки: форму тримає заливка;
     · картка тарифу — всередині ще одна заливка, яка перекладає абстрактні
       одиниці в конкретний результат («270 кредитів = 15 відео»).

   Вантажиться ПІСЛЯ skin.css: класи тут нові й ні з чим не конфліктують, але
   якщо елемент несе ще й `.panel`/`.card`, тай-брейк має лишатись за цим
   файлом.

   ── Що де застосовується ──────────────────────────────────────────────────
   .ui-deck   — деки налаштувань (Studio, Композер, Бренд, Налаштування)
   .ui-sel    — випадайник (розмітка й логіка: js/ui_select.js)
   .ui-tiles  — вітрини (Галерея, Бібліотека, Огляд)
   .ui-bar    — нижній рядок дії з ціною
   .ui-stats  — смуга показників, де герой — число
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 0. Кольорові переливи ────────────────────────────────────────────────
   Зчитано з живих сторінок higgsfield.ai через getComputedStyle — це їхні
   справжні значення, не підбір на око. Вони будують колір НЕ заливкою
   картки, а кількома напівпрозорими радіальними плямами по кутах:

     radial-gradient(72px 48px at 0% 0%, rgba(колір,.16), transparent) ×4 кути

   Ключова цифра — .16. Плями ледь помітні поодинці, але разом дають картці
   власне свічення, і при цьому НЕ фарбують текст на ній. Суцільна кольорова
   заливка так не вміє: вона з'їдає контраст і робить кожну картку рекламою.

   🛑 Межа, яку тут проведено навмисно: переливи — це АТМОСФЕРА ПОВЕРХНІ, а
   не бренд. Бурштин у нас означає «сюди тиснути», і якщо кольори підуть на
   кнопки, акцент перестане читатись — рівно та сама помилка, через яку
   рожевий довелось виполювати з 33 рядків. Тому колір живе на площинах
   (герої, картки-категорії, заглушки вітрини, великі числа), а всі дії
   лишаються бурштиновими.

   Відтінки прив'язані до СЕНСУ розділу, а не до настрою: око запам'ятовує
   «бібліотека блакитна», і вітрина стає впізнаваною ще до читання підпису. */
:root {
  /* 🛑 УСЯ П'ЯТІРКА ПЕРЕВЕДЕНА В ТЕПЛУ РОДИНУ.
     Було: рожевий 236,72,120, фіолетовий 139,110,255, блакитний
     120,235,255, зелений 61,220,132 — чотири з п'яти холодні. Разом
     із теплою базою (тон 60-85) вони давали рівно те, що дизайн-код
     називає дешевим виглядом: різнокольорові плями на одному тлі.
     Рожевий тут ще й той самий, від якого ми відмовились у бренді.

     Задум лишається: відтінок прив'язаний до СЕНСУ розділу, щоб око
     запам'ятало «бібліотека — своя». Але різниця тепер усередині
     теплої половини кола (40-95°), а не стрибком на протилежний бік.
     Плитки далі відрізняються, і жодна не випадає з родини.

     Виміряно: класи .ui-hue-* нікому не присвоєні, тож самі по собі
     ці токени малюють лише через nth-child у вітринах і три
     градієнти-картки. Тому заміна тут — найдешевший спосіб
     полагодити всі місця одразу. */
  --hue-amber:  240, 165, 0;     /* дія, Studio, кредити */
  --hue-rose:   214, 112, 66;    /* теракота: публікація, композер */
  --hue-violet: 186, 138, 104;   /* глина: аналітика, дослідження */
  --hue-cyan:   206, 186, 140;   /* пісок: бібліотека, дані */
  --hue-green:  168, 166, 112;   /* олива: успіх, опубліковане */
}
.ui-hue-amber  { --hue: var(--hue-amber); }
.ui-hue-rose   { --hue: var(--hue-rose); }
.ui-hue-violet { --hue: var(--hue-violet); }
.ui-hue-cyan   { --hue: var(--hue-cyan); }
.ui-hue-green  { --hue: var(--hue-green); }

/* Свічення по кутах. Псевдоелемент, а не фон: сама поверхня може бути
   картинкою, відео чи заливкою — свічення лягає поверх будь-чого й ніколи
   не перехоплює вказівник. */
.ui-glow { position: relative; }
.ui-glow::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(72px 48px at 0% 0%,     rgba(var(--hue, var(--hue-amber)), .16), transparent 100%),
    radial-gradient(72px 48px at 100% 0%,   rgba(var(--hue, var(--hue-amber)), .16), transparent 100%),
    radial-gradient(72px 48px at 0% 100%,   rgba(var(--hue, var(--hue-amber)), .16), transparent 100%),
    radial-gradient(72px 48px at 100% 100%, rgba(var(--hue, var(--hue-amber)), .16), transparent 100%);
}
.ui-glow > * { position: relative; z-index: 2; }

/* Одна пляма знизу-зліва — для смуг, пігулок і невисоких поверхонь, де
   чотири кути злились би в суцільний колір. */
.ui-wash {
  background:
    radial-gradient(60% 90% at 26% 100%, rgba(var(--hue, var(--hue-amber)), .20), transparent 100%),
    var(--panel);
}

/* Герой: колір заливає верх поверхні й РОЗЧИНЯЄТЬСЯ у фоні сторінки, а не
   обривається лінією. Другий шар — та сама вертикаль від прозорого до
   кольору фону — і є тим розчиненням. */
.ui-hero {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(var(--bg-rgb), 0) 0%, rgba(var(--bg-rgb), .88) 78%, rgb(var(--bg-rgb)) 100%),
    linear-gradient(160deg,
      rgba(var(--hue, var(--hue-amber)), .40) 0%,
      rgba(var(--hue, var(--hue-amber)), .16) 34%,
      rgba(var(--hue-rose), .10) 62%,
      var(--panel) 100%);
}
/* Технічна сітка поверх героя — дві лінії по .04 через 45px. Дає поверхні
   масштаб: без неї великий градієнт читається як розмита картинка. */
.ui-hero-grid::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .04) 0 1px, transparent 1px),
    linear-gradient(rgba(255, 255, 255, .04) 0 1px, transparent 1px);
  background-size: 45px 45px;
  mask-image: linear-gradient(180deg, #000 0%, transparent 82%);
}

/* Скрим під текстом на медіа. 🛑 Текст НІКОЛИ не лягає просто на кадр: на
   світлому кадрі він зникає. Знизу вгору — від кольору панелі до прозорого. */
.ui-scrim::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 62%;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, .78) 76%, rgba(0, 0, 0, .9) 100%);
}

/* Заголовок із переливом. Використовувати ЛИШЕ на великих кеглях: на 12px
   градієнт у тексті з'їдає контраст і читається як розмитість. */
.ui-gtext {
  background: linear-gradient(180deg, var(--text) 0%, rgba(var(--hue, var(--hue-amber)), .85) 130%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ── 1. Дека: смуги з іменами замість коробок ─────────────────────────────
   Група — це ЗАГОЛОВОК і волосяна лінія, а не рамка навколо. Причина не
   естетична: коробка додає власний внутрішній відступ, і кожна наступна
   група починається на кілька пікселів правіше за попередню. У деки лівий
   край РІВНО ОДИН — заголовок, підпис поля й сам контрол стоять на одній
   вертикалі. Studio має власну копію цих правил, прив'язану до #cmpzDrawer:
   там ті самі класи обслуговують ще й Автопілот із Батчем, і глобальна
   правка поїхала б у розділи, яких ми не чіпаємо. */
.ui-deck { display: block; }
.ui-deck-strip { padding: 14px 0; border-top: 1px solid var(--border-soft); }
.ui-deck-strip:first-child { padding-top: 0; border-top: 0; }
.ui-deck-strip:last-child { padding-bottom: 0; }
.ui-deck-head {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: 10px;
  font: 700 var(--fs-10)/1 var(--sans);
  color: var(--accent);
}
.ui-deck-head .sub {
  font: 400 var(--fs-11)/1.3 var(--sans);
  color: var(--text-mute);
  text-transform: none;
  letter-spacing: -.006em;
}
.ui-deck-head .ui-tag { margin-left: 0; }
/* Дія праворуч у заголовку групи («Налаштувати →», «Уся галерея →»). */
.ui-deck-head .act {
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-mute);
  font: 500 var(--fs-11)/1 var(--sans);
  text-transform: none;
  letter-spacing: -.006em;
  cursor: pointer;
}
.ui-deck-head .act:hover { color: var(--accent-hi); }

.ui-tag {
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  background: var(--accent-wash-2);
  color: var(--accent-hi);
  font: 700 8.5px/1.5 var(--sans);
}

.ui-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px 16px;
}
.ui-grid-wide > * { grid-column: 1 / -1; }
.ui-field { display: flex; flex-direction: column; gap: var(--sp-6); min-width: 0; }
.ui-field-wide { grid-column: 1 / -1; }
.ui-label {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  font: 700 var(--fs-10)/1.35 var(--sans);
  color: var(--text-dim);
}

/* ── 2. Випадайник ────────────────────────────────────────────────────────
   Нативний <select> малюється засобами ОС: у темній темі приїжджала світла
   системна панель, яка ігнорує і токени, і шрифт. Тут рядок двоповерховий —
   назва плюс те, за що цю опцію обирають: підказка в `title` для вибору не
   працює, бо саме за описом і обирають. Логіка — js/ui_select.js. */
.ui-sel { position: relative; min-width: 0; }
.ui-sel-btn {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  width: 100%;
  min-width: 0;
  padding: 7px 10px;
  border: 0;
  text-align: left;
  background: var(--fill-1);
  color: var(--text);
  border-radius: var(--radius-sm);
  cursor: pointer;
  /* 🛑 Кегль КНОПЦІ, а не лише підпису всередині. Внутрішній `.n` свій
     шрифт мав, а сама кнопка — ні, тож її коробка успадковувала дефолт
     браузера для <button>: 13.3333px. Це видно на всьому, що лежить у
     кнопці поза `.n`, — на стрілці й на метриках рядка. Виміряно у
     Пошті, Грошах і Налаштуваннях. */
  font: 600 var(--fs-12)/1.25 var(--sans);
  font-family: var(--sans);
  transition: background var(--t-fast) var(--ease);
}
.ui-sel-btn:hover:not(:disabled) { background: var(--fill-2); }
.ui-sel-btn:disabled { cursor: default; opacity: .75; }
.ui-sel.open .ui-sel-btn { background: var(--fill-2); box-shadow: inset 0 0 0 1px var(--accent-edge-hi); }
.ui-sel-cur { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.ui-sel-cur .n {
  font: 600 var(--fs-12)/1.25 var(--sans);
  color: var(--text);
  letter-spacing: -.012em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ui-sel-cur .h {
  font: 400 var(--fs-10)/1.3 var(--sans);
  color: var(--text-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ui-sel-chev { margin-left: auto; color: var(--text-mute); font-size:  var(--fs-10); }

/* left/top/width/max-height проставляє place() у JS. Меню лежить у <body>
   (портал) із ABSOLUTE у координатах сторінки — так його не може ні
   обрізати `overflow: hidden`, ні перепідпорядкувати предок із трансформом.
   🛑 Було `fixed`, і це ламалось: елемент із transform стає containing
   block для fixed-нащадків, тож анімація появи розділу зсувала меню на
   ширину бічного меню. Див. js/ui_select.js. */
.ui-sel-menu {
  position: absolute;
  z-index: 400;
  /* 🛑 ПІДЛОГИ ШИРИНИ ТУТ НЕМАЄ, і це навмисно. Вона стояла (200px) і
     була мертвою: js/ui_select.js виставляє `min-width` ІНЛАЙНОМ, а
     інлайн завжди сильніший за таблицю стилів. Виміряно — меню
     виходило 139px попри «підлогу» 200. Підлога живе в JS (MIN_W)
     разом зі стелею, бо обидві залежать від того самого виміру. */
  /* Підпис пункту переносимо по СЛОВАХ. Без цього довгий підпис у
     вузькому меню ламався по літері — виміряно в Studio. */
  overflow-wrap: break-word;
  max-height: 280px;
  padding: 5px;
  overflow-y: auto;
  background: var(--elevated);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop), inset 0 0 0 1px var(--border);
}
.ui-sel-opt {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: 100%;
  padding: 8px 10px;
  border: 0;
  text-align: left;
  background: transparent;
  border-radius: var(--ctl-radius-sm);
  cursor: pointer;
  font-family: var(--sans);
}
.ui-sel-opt:hover { background: var(--fill-2); }
.ui-sel-opt.on { background: var(--accent-wash-2); }
.ui-sel-opt .n { font: 600 var(--fs-12)/1.2 var(--sans); color: var(--text); letter-spacing: -.012em; }
.ui-sel-opt.on .n { color: var(--accent-hi); }
.ui-sel-opt .h { font: 400 var(--fs-10)/1.35 var(--sans); color: var(--text-mute); }

/* ── 3. Вітрина ───────────────────────────────────────────────────────────
   🛑 ГОЛОВНЕ ПРАВИЛО: плитка має ФІКСОВАНУ пропорцію, і медіа заповнює її
   повністю. Було навпаки — плитка 430px заввишки з піктограмою 24px
   посередині порожнечі; дві такі займали весь екран і не показували нічого.
   У Higgsfield на тій самій ширині стоїть чотири колонки, і кожна щось
   показує. Щільність тут не про естетику: вітрина існує, щоб ОКОМ знайти
   потрібне, а для цього треба бачити багато варіантів одночасно. */
.ui-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--tile-min, 200px), 1fr));
  gap: var(--sp-12);
}
.ui-tiles-sm { --tile-min: 150px; }
.ui-tiles-lg { --tile-min: 260px; }

.ui-tile {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 0;
  border: 0;
  text-align: left;
  background: none;
  cursor: pointer;
  font-family: var(--sans);
}
.ui-tile-media {
  position: relative;
  aspect-ratio: var(--tile-ratio, 4 / 5);
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--fill-1);
  box-shadow: inset 0 0 0 1px var(--border-soft);
  transition: box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.ui-tile:hover .ui-tile-media {
  box-shadow: inset 0 0 0 1px var(--accent-edge-hi);
  transform: translateY(-1px);
}
.ui-tile-media > img,
.ui-tile-media > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Заглушка. Порожнє місце — це не «ще нічого немає», а «незрозуміло, що тут
   буде». Тому заглушка ГОВОРИТЬ, що саме тут з'явиться, і тримає ту саму
   пропорцію, що й справжнє медіа, — сітка не стрибне, коли воно приїде. */
.ui-tile-ph {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 14px;
  text-align: center;
  background:
    radial-gradient(80% 70% at 22% 8%, rgba(var(--hue, var(--hue-amber)), .22), transparent 100%),
    radial-gradient(70% 60% at 88% 96%, rgba(var(--hue2, var(--hue-rose)), .16), transparent 100%),
    var(--fill-1);
}

/* 🛑 Порожня вітрина не має бути сірою. Поки медіа немає, плитки беруть
   відтінки по колу — п'ять кроків, тобто сусідні ніколи не збігаються, а
   сітка з восьми заглушок читається як набір, а не як прогалина. Це і є
   відповідь на «не залишай пустого місця»: місце зайняте кольором і
   підписом, який каже, що саме тут з'явиться. */
.ui-tiles > .ui-tile:nth-child(5n + 1) { --hue: var(--hue-amber);  --hue2: var(--hue-rose); }
.ui-tiles > .ui-tile:nth-child(5n + 2) { --hue: var(--hue-cyan);   --hue2: var(--hue-violet); }
.ui-tiles > .ui-tile:nth-child(5n + 3) { --hue: var(--hue-violet); --hue2: var(--hue-rose); }
.ui-tiles > .ui-tile:nth-child(5n + 4) { --hue: var(--hue-green);  --hue2: var(--hue-cyan); }
.ui-tiles > .ui-tile:nth-child(5n + 5) { --hue: var(--hue-rose);   --hue2: var(--hue-amber); }
.ui-tile-ph .g { color: var(--text-mute); opacity: .55; }
.ui-tile-ph .g svg { width: 22px; height: 22px; }
.ui-tile-ph .t {
  font: 500 var(--fs-10)/1.4 var(--sans);
  color: var(--text-mute);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ui-tile-badge,
.ui-tile-glyph {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  padding: 3px 7px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .58);
  backdrop-filter: blur(6px);
  color: #fff;
  font: 600 var(--fs-10)/1.4 var(--sans);
  letter-spacing: -.006em;
}
.ui-tile-badge { top: 7px; left: 7px; }
.ui-tile-glyph { bottom: 7px; left: 7px; padding: 4px; }
.ui-tile-glyph svg { width: 11px; height: 11px; display: block; }

/* Дії проявляються на наведення й НЕ зсувають розкладку. */
.ui-tile-acts {
  position: absolute;
  top: 7px;
  right: 7px;
  z-index: 2;
  display: flex;
  gap: var(--sp-4);
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease);
}
.ui-tile:hover .ui-tile-acts,
.ui-tile:focus-within .ui-tile-acts { opacity: 1; }
.ui-tile-act {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--ctl-radius-sm);
  background: rgba(0, 0, 0, .6);
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
}
.ui-tile-act:hover { background: var(--accent-solid); color: #1a1204; }
.ui-tile-act svg { width: 13px; height: 13px; }

.ui-tile-body { padding: 8px 2px 0; min-width: 0; }
/* 🛑 Дві лінії, а не одна з трьома крапками. Назви товарів і персонажів
   стабільно довші за колонку, і обрізання посеред слова («Ця штука мене
   вр…») робить вітрину нечитабельною саме там, де по ній шукають. */
.ui-tile-title {
  font: 600 var(--fs-12)/1.35 var(--sans);
  color: var(--text);
  letter-spacing: -.012em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ui-tile-sub {
  margin-top: 2px;
  font: 400 var(--fs-10)/1.4 var(--sans);
  color: var(--text-mute);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ui-tile-meta {
  margin-top: 5px;
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  flex-wrap: wrap;
  font: 400 var(--fs-10)/1.3 var(--sans);
  color: var(--text-dim);
}

/* ── 4. Картка сутності ───────────────────────────────────────────────────
   Рядок, а не коробка: піктограма, назва, один рядок пояснення, статус
   навпроти, дія праворуч. Чотири однакові суцільно-акцентні кнопки на одному
   екрані знецінюють акцент — тому дія тут вторинна, а бурштин лишається
   один на екран. */
.ui-rows { display: flex; flex-direction: column; gap: var(--sp-2); }
.ui-row {
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  background: transparent;
  transition: background var(--t-fast) var(--ease);
}
.ui-row:hover { background: var(--fill-1); }
.ui-row-ic {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--ctl-radius-sm);
  background: var(--fill-1);
  color: var(--text-dim);
}
.ui-row-ic svg { width: 15px; height: 15px; }
.ui-row-txt { flex: 1 1 auto; min-width: 0; }
.ui-row-name { font: 600 var(--fs-13)/1.3 var(--sans); color: var(--text); letter-spacing: -.012em; }
.ui-row-sub {
  font: 400 var(--fs-11)/1.4 var(--sans);
  color: var(--text-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ui-row-end { flex: 0 0 auto; display: flex; align-items: center; gap: var(--sp-8); }

/* Статус — тихий чіп. Кольори беруться з семантики стану, а не з випадкової
   палітри: рожевий «не підключено» був чужим і в бренді, і в сенсі. */
.ui-state {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--fill-1);
  color: var(--text-mute);
  font: 600 var(--fs-10)/1.5 var(--sans);
  letter-spacing: -.006em;
  white-space: nowrap;
}
.ui-state::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: .8;
}
.ui-state.on { background: rgba(var(--ok-rgb), .12); color: var(--ok-hi); }
.ui-state.off { background: var(--fill-1); color: var(--text-dim); }
.ui-state.warn { background: var(--accent-wash-2); color: var(--accent-hi); }
.ui-state.bad { background: rgba(var(--danger-rgb), .12); color: var(--danger-hi); }
.ui-state.plain::before { display: none; }

/* ── 5. Рядок дії ─────────────────────────────────────────────────────────
   🛑 grid, а не flex-wrap. flex-wrap переносить ЦІЛИЙ елемент на новий
   рядок, тому блок «ціна + кнопка» падав під чипи щойно їх ставало більше.
   minmax(0,1fr) дозволяє лівій частині стискатись, і пара «ціна + дія»
   лишається на місці за будь-якої ширини. */
.ui-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-12);
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
}
.ui-bar-left { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; }
.ui-bar-right { display: flex; align-items: center; gap: var(--sp-12); }
.ui-cost { font: 700 var(--fs-13)/1 var(--sans); color: var(--text); white-space: nowrap; }
.ui-cost .u { font-weight: 500; color: var(--text-mute); }
/* Ціна в доларах — НАША закупівельна, тобто пряма підказка про маржу поруч
   із ціною клієнта. Видно лише власнику (див. isOwnerView). */
.ui-cost-usd { font: 500 var(--fs-11)/1 var(--mono, var(--sans)); color: var(--text-dim); white-space: nowrap; }

/* ── 6. Смуга показників ──────────────────────────────────────────────────
   Герой — число. Підпис дрібний і згори, значення велике, пояснення знизу:
   око чіпляється за цифру, а не за заголовок. */
.ui-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0;
}
.ui-stat { padding: 2px 18px; border-left: 1px solid var(--border-soft); min-width: 0; }
.ui-stat:first-child { padding-left: 0; border-left: 0; }
.ui-stat-k {
  font: 700 var(--fs-10)/1 var(--sans);
  color: var(--text-dim);
}
.ui-stat-v {
  margin: 9px 0 6px;
  font: 300 var(--fs-32)/1 var(--sans);
  color: var(--text);
  letter-spacing: -.03em;
}
.ui-stat-v.accent { color: var(--accent); }
.ui-stat-v .u { font-size:  var(--fs-14); color: var(--text-mute); letter-spacing: -.01em; }
.ui-stat-sub { font: 400 var(--fs-11)/1.4 var(--sans); color: var(--text-mute); }

/* ── 7. Сегментоване перемикання ──────────────────────────────────────────
   Один контейнер із заливкою, всередині — рівні частки. Було: кілька
   однакових кнопок поспіль, де активна відрізнялась лише кольором, і група
   не читалась як ОДИН перемикач. */
.ui-seg {
  display: inline-flex;
  gap: var(--sp-2);
  padding: 3px;
  border-radius: 999px;
  /* 🛑 НЕ --fill-1: сегмент часто лежить на картці, і картка — теж
     --fill-1. Виміряно на автопілоті: доріжка 235x30 того самого кольору,
     що поверхня під нею, тобто жолоба не видно й «вибране» ні з чого не
     піднімається. Доріжка — це заглибина (див. --well), а вибрана
     кнопка — щабель, піднятий із неї. */
  background: var(--well);
}
.ui-seg-btn {
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-mute);
  font: 600 var(--fs-12)/1 var(--sans);
  letter-spacing: -.012em;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.ui-seg-btn:hover { color: var(--text); }
/* 🛑 БУЛО БУРШТИНОВЕ, СТАЛО ЯСКРАВІСТЬ — та сама причина, що й у рейці.
   Бурштин у застосунку належить ДВОМ речам: ціні й головній дії, і не
   більше ніж по одній на екран. Поки сегмент світився бурштином, на екрані
   Studio його ділили перемикач способу й кнопка за 111 кредитів — тобто
   найважливіше на екрані було рівно таким самим на вигляд, як вибір
   вкладки. */
.ui-seg-btn.on { background: var(--fill-3); color: var(--text); }

/* ── ТРИ ДВЕРІ ───────────────────────────────────────────────────────────
   Стоїть першим рядком робочої зони на Чаті, Композері й Studio.

   Це не дубль рейки. Рейка відповідає на питання «де я», і відповідає
   назвою розділу: «Чат», «Композер», «Studio». Три двері відповідають на
   інше питання — «як я це зроблю», і відповідають ДІЄЮ: радитись,
   зібрати самому, зняти ролик. Назва розділу не каже нікому, що Studio
   зніме ролик за нього, а Композер — ні.

   Головне ж: поки це були три пункти рейки серед дванадцяти, вибір між
   ними виглядав як вибір між «Календарем» і «Галереєю» — тобто як
   перехід, а не як розвилка. Тепер видно, що двері три й вони поруч. */
.doors{
  display: flex; align-items: center; gap: var(--sp-14); flex-wrap: wrap;
  margin: 0 0 18px;
}
.doors .n{ font: 500 var(--fs-12)/1.4 var(--sans); color: var(--text-mute); }
.doors .ui-seg-btn{ padding: 8px 16px; font-size:  var(--fs-12); }

/* ── 8. Вузькі екрани ─────────────────────────────────────────────────────
   Смуга показників на телефоні — не колонка з розділювачами зліва: вони
   малюють сходинку там, де її немає. */
@media (max-width: 680px) {
  .ui-tiles { --tile-min: 140px; gap: var(--sp-10); }
  .ui-grid { grid-template-columns: 1fr; }
  .ui-stats { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 14px 0; }
  .ui-stat { padding: 0; border-left: 0; }
  .ui-stat-v { font-size: 26px; margin: 6px 0 4px; }
  .ui-bar { grid-template-columns: 1fr; }
  .ui-bar-right { justify-content: flex-end; }
  .ui-row { gap: 9px; padding: 10px 8px; }
}

/* ── 9. Рейл вибору (плитки «Відео / Фото / Карусель») ────────────────────
   Народився в композері Studio й виявився найсильнішим контролом у
   застосунку. Чому він працює краще за ряд чипів:

     · піктограма несе сенс швидше за слово — око впізнає «відео» за формою
       кадру, не читаючи;
     · плитки стоять в ОДНІЙ заливці, тобто читаються як один перемикач, а
       не як три окремі кнопки поруч;
     · обраний стан — не просто інший колір, а підняття: світліша заливка
       плюс тепла волосяна рамка. Різницю видно боковим зором;
     · вертикальний рейл не з'їдає рядок керування, горизонтальний лягає
       туди, де місця по ширині більше.

   🛑 Це контрол для ВЗАЄМОВИКЛЮЧНОГО вибору з 2-5 варіантів, які людина
   змінює нечасто: тип поста, тека бібліотеки, режим переписки. Для частих
   перемикань лишається `.ui-seg` (пігулка), для довгих списків — `.ui-sel`.
   Шість плиток і більше — це вже сітка, а не рейл. */
/* Ванна темніша за плитки в ній — саме ця різниця й робить плитку плиткою,
   а не пласким прямокутником. Внутрішня тінь по верхньому краю дає відчуття
   заглиблення, у якому вони лежать. */
.ui-pick {
  display: flex;
  gap: var(--sp-4);
  padding: 4px;
  background: var(--fill-1);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .22);
  border-radius: calc(var(--radius-lg) - 6px);
  width: max-content;
  max-width: 100%;
}
.ui-pick-col { flex-direction: column; }
.ui-pick-fill { width: 100%; }
.ui-pick-fill > * { flex: 1 1 0; }

/* 🛑 Селектор навмисно подвійний (`button.chip` теж) і скрізь стоїть
   `height: auto`. Причина зміряна: `skin.css` задає всім чипам ФІКСОВАНУ
   висоту керування, і плитка мовчки стискалась із 52px до 34 — піктограма з
   підписом не вміщались, рейл у Композері виглядав інакше за той самий рейл
   у Studio, хоча CSS був спільний. Різниця в 16px на око не читається як
   «висота», вона читається як «інший компонент». */
.ui-pick > button,
.ui-pick > button.chip,
.ui-pick > .ui-pick-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: var(--pick-w, 76px);
  min-width: var(--pick-w, 76px);
  height: auto;
  min-height: 0;
  padding: 9px 6px;
  border: 0;
  background: transparent;
  color: var(--text-mute);
  border-radius: calc(var(--radius) - 4px);
  cursor: pointer;
  /* 🛑 Був лише `font-family`, без кегля й ваги — тобто плитка
     набиралась дефолтом браузера для <button>: 13.3333px/400.
     Виміряно на живих вкладках галереї, бібліотеки й досліджень.
     Кегль тепер приходить токеном --pick-font. */
  font: var(--pick-font);
  text-align: center;
  transition: background var(--m-base, 160ms) var(--m-ease, ease),
              color var(--m-base, 160ms) var(--m-ease, ease),
              transform var(--m-fast, 120ms) var(--m-ease, ease);
}
/* Наведення видно ОДРАЗУ: заливка на крок світліша плюс власна тінь, тобто
   плитка не просто підсвітилась, а піднялась. Було `--fill-2` без тіні —
   різниця з незачепленою плиткою читалась лише впритул. */
/* 🛑 Контур має бути ВИДНО і в незачепленої плитки. Раніше форму їй
   давала сама заливка, а межа зʼявлялась лише в обраної — через це рейл
   читався як одна пляма з однією підсвіченою ділянкою, а не як набір
   окремих кнопок. Тепер межа є завжди, просто тиха. */
.ui-pick > button,
.ui-pick > button.chip,
.ui-pick > .ui-pick-btn,
.ui-pick > .net-toggle {
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .07),
    inset 0 1px 0 rgba(255, 255, 255, .05);
}
.ui-pick > button:hover,
.ui-pick > button.chip:hover,
.ui-pick > .ui-pick-btn:hover {
  background: var(--fill-3);
  color: var(--text);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .16),
    inset 0 1px 0 rgba(255, 255, 255, .10),
    0 2px 8px -2px rgba(0, 0, 0, .4);
}
.ui-pick > button:active, .ui-pick > button.chip:active { transform: scale(.97); }

/* Обраний: заливка + тепла рамка + бурштиновий підпис. Три сигнали тут
   виправдані — саме цей стан людина шукає очима щоразу, повертаючись до
   екрана. */
/* 🛑 Обраний = БУРШТИНОВИЙ ЦІЛКОМ, разом із піктограмою. Виміряно
   getComputedStyle: у Studio колір іконки був rgb(240,165,0), у Композері
   білий — бо амбру давало правило `skin.css` для `.st-format-card.selected
   .st-format-ic`, тобто прив'язане до класу ОДНОГО розділу, а не до
   спільного компонента. Поки колір живе поза компонентом, збіг між
   екранами — випадковість, яка ламається від будь-якої правки. */
/* Обраний стан підсилено: тепла рамка з 12% до 42%, світло по верхній
   кромці й м'який бурштиновий ореол назовні. Заливка лишається НЕЙТРАЛЬНОЮ —
   суцільний бурштин тут зробив би плитку схожою на кнопку-дію, а це вибір, а
   не дія. Колір несуть піктограма, підпис і рамка. */
.ui-pick > button.active,
.ui-pick > button.chip.active,
.ui-pick > button.selected,
.ui-pick > button[aria-pressed="true"],
.ui-pick > .net-toggle.active {
  background: var(--pick-active-bg);
  color: var(--pick-active-fg);
  box-shadow:
    inset 0 0 0 1.5px var(--pick-active-ring),
    inset 0 1px 0 rgba(255, 255, 255, .13),
    0 2px 10px -4px rgba(0, 0, 0, .5);
}
.ui-pick > button.active:hover,
.ui-pick > button.chip.active:hover,
.ui-pick > button.selected:hover,
.ui-pick > .net-toggle.active:hover {
  background: var(--pick-active-bg);
  color: var(--pick-active-fg);
  box-shadow:
    inset 0 0 0 1.5px var(--pick-active-ring),
    inset 0 1px 0 rgba(255, 255, 255, .16),
    0 5px 16px -4px rgba(0, 0, 0, .55);
}
.ui-pick > button.active .lbl,
.ui-pick > button.selected .lbl,
.ui-pick > button.active > span:last-child,
.ui-pick > button.chip.active > span:last-child,
/* 🛑 Підпис обраної плитки теж НЕ бурштиновий — інакше правило вище
   скасовувалось би цим рядком, і колір повертався б через задні двері. */
.ui-pick > button.selected > span:last-child { color: var(--pick-active-fg); }

.ui-pick [data-icon], .ui-pick .svg-ic { width: 18px; height: 18px; display: block; }
.ui-pick [data-icon] svg, .ui-pick .svg-ic svg { width: 18px; height: 18px; display: block; }
/* Підпис у два рядки, а не обрізаний: «Зображення» і «Відео-Reel» довші за
   плитку, і три крапки посеред слова роблять рейл нечитабельним. */
.ui-pick > button > span:last-child,
.ui-pick > button.chip > span:last-child {
  font: 600 var(--fs-11)/1.2 var(--sans);
  letter-spacing: -.01em;
  text-align: center;
  overflow-wrap: anywhere;
}

/* Перемикачі платформ мають власну розмітку (`netToggleHtml` у studio.js і
   composer.js віддають «іконка + підпис»), але це той самий контрол — тож
   вони теж плитки рейла. Багатовибірні: активних може бути кілька. */
.ui-pick > .net-toggle {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  width: var(--pick-w, 76px);
  min-width: var(--pick-w, 76px);
  height: auto;
  min-height: 0;
  padding: 9px 6px;
  border: 0;
  background: transparent;
  color: var(--text-mute);
  border-radius: calc(var(--radius) - 4px);
  cursor: pointer;
  font-family: var(--sans);
  transition: background var(--m-base, 160ms) var(--m-ease, ease),
              color var(--m-base, 160ms) var(--m-ease, ease),
              transform var(--m-fast, 120ms) var(--m-ease, ease);
}
.ui-pick > .net-toggle:hover:not(:disabled) { background: var(--fill-2); color: var(--text-dim); }
.ui-pick > .net-toggle:active:not(:disabled) { transform: scale(.97); }
.ui-pick > .net-toggle.active {
  background: var(--fill-3);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border-warm);
}
.ui-pick > .net-toggle.active > span:last-child { color: var(--accent); }
/* Непідключена платформа: видно, що вона існує, і видно, що недосяжна. */
.ui-pick > .net-toggle:disabled { opacity: .38; cursor: not-allowed; }
.ui-pick > .net-toggle > span:last-child {
  font: 600 var(--fs-10)/1.2 var(--sans);
  letter-spacing: -.01em;
  text-align: center;
  overflow-wrap: anywhere;
}
.ui-pick .nt-ic { width: 20px; height: 20px; display: block; }
.ui-pick .nt-ic svg, .ui-pick .nt-ic .net-ico { width: 20px; height: 20px; display: block; }

/* Компактний варіант — для рядків, де вертикальної висоти обмаль. */
.ui-pick-sm { --pick-w: 84px; }
.ui-pick-sm > button, .ui-pick-sm > button.chip { padding: 7px 6px; gap: var(--sp-2); }
.ui-pick-sm [data-icon] svg, .ui-pick-sm .svg-ic svg { width: 15px; height: 15px; }
.ui-pick-sm > button > span:last-child { font-size:  var(--fs-10); }

@media (max-width: 680px) {
  .ui-pick-col { flex-direction: row; width: 100%; }
  .ui-pick-col > * { flex: 1 1 0; min-width: 0; }
}

/* ── 10. Повзунок ─────────────────────────────────────────────────────────
   Для величин із природним порядком і кроком (тривалість, кількість,
   гучність). 🛑 Випадайник для тривалості був помилкою за суттю: людина
   думає «трохи довше», а не «пункт номер три». Повзунок дає цей рух
   напряму, а поточне значення підписане великим — щоб не гадати. */
.ui-range { display: flex; flex-direction: column; gap: var(--sp-8); min-width: 0; }
.ui-range-top { display: flex; align-items: baseline; gap: var(--sp-8); }
.ui-range-val { font: 300 22px/1 var(--sans); color: var(--text); letter-spacing: -.02em; }
.ui-range-val .u { font: 500 var(--fs-11)/1 var(--sans); color: var(--text-mute); margin-left: 3px; }
.ui-range-note { margin-left: auto; font: 400 var(--fs-10)/1.3 var(--sans); color: var(--text-mute); }

.ui-range input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 26px;
  background: transparent;
  cursor: pointer;
  margin: 0;
}
.ui-range input[type="range"]::-webkit-slider-runnable-track {
  height: 5px;
  border-radius: 999px;
  /* Заповнену частину малює градієнт, який рахує JS через --fill-pct: без
     цього доріжка ліворуч і праворуч від бігунка виглядає однаково, і
     значення читається лише з підпису. */
  background: linear-gradient(90deg,
    var(--accent-solid) 0 var(--fill-pct, 50%),
    var(--fill-2) var(--fill-pct, 50%) 100%);
}
.ui-range input[type="range"]::-moz-range-track {
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(90deg,
    var(--accent-solid) 0 var(--fill-pct, 50%),
    var(--fill-2) var(--fill-pct, 50%) 100%);
}
.ui-range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -5.5px;
  border-radius: 50%;
  background: var(--accent-solid);
  box-shadow: 0 0 0 4px var(--accent-wash-3);
  transition: box-shadow var(--m-fast, 120ms) var(--m-ease, ease);
}
.ui-range input[type="range"]::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border: 0;
  border-radius: 50%;
  background: var(--accent-solid);
  box-shadow: 0 0 0 4px var(--accent-wash-3);
}
.ui-range input[type="range"]:hover::-webkit-slider-thumb,
.ui-range input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 6px var(--accent-edge);
}
.ui-range input[type="range"]:focus-visible { outline: none; }
/* Позначки кроків — щоб було видно, що значень скінченна кількість. */
.ui-range-ticks {
  display: flex;
  justify-content: space-between;
  font: 500 var(--fs-10)/1 var(--sans);
  color: var(--text-dim);
}
.ui-range-ticks > span.on { color: var(--accent-hi); }
