/* Raycore Client Area — GRPhoto Design System

   Палітра (з grphoto-design-system/colors_and_type.css):
   - Pure black     #000000  → headers, nav, table thead, primary CTA
   - Cool off-white #f1f2f4  → page background
   - Sky blue       #47a2da  → link / accent / CTA hover text
   - Slate grey     #8c97a1  → secondary text, meta, dim
   - Divider        #d5d9dd  → borders, separators

   Структурні відтінки сірого (внутрішні UI-зони):
   - #ffffff   card body / modal body
   - #e3e6e9   card footer (структурна зона — трохи темніше за body)
   - #e6e8ea   disabled inputs / modal footer / focus state
   - #f1f2f4   form input bg (= page bg)
*/

/* Підмінюємо Bootstrap primary на sky-blue. Primary тепер використовується ЛИШЕ для посилань
   та .text-primary/.bg-primary утиліт. Кнопка .btn-primary (нижче) — окрема історія, виконана
   у GRPhoto "dark CTA" стилі (чорний фон, sky-blue текст на hover). */
:root {
    --bs-primary: #47a2da;
    --bs-primary-rgb: 71, 162, 218;
    --bs-link-color: #47a2da;
    --bs-link-color-rgb: 71, 162, 218;
    --bs-link-hover-color: #2789c5;
    --bs-link-hover-color-rgb: 39, 137, 197;

    /* Розкриваємо токени GRPhoto для re-use у компонентах */
    --gr-dark: #000000;
    --gr-light: #f1f2f4;
    --gr-primary: #47a2da;
    --gr-secondary: #8c97a1;
    --gr-divider: #d5d9dd;
    --gr-gold: #8c7a4a; /* брендовий золотистий акцент (логотип, мітка «Commercial») */
    --gr-fav: #d64562;  /* серце «улюблене» */
    --gr-muted: #6d7780; /* приглушений сірий на темному тлі — перемикачі кошика й далі */
}

/* GRPhoto "dark CTA" — стиль primary-кнопки клієнтської зони.
   Чорний фон, light-grey текст; на hover фон лишається чорним, текст синіє.
   Це сигнатурний рух системи — не змінювати без обговорення. */
.btn-primary {
    --bs-btn-bg: #000000;
    --bs-btn-border-color: #000000;
    --bs-btn-color: #f1f2f4;
    --bs-btn-hover-bg: #000000;
    --bs-btn-hover-border-color: #000000;
    --bs-btn-hover-color: #47a2da;
    --bs-btn-active-bg: #000000;
    --bs-btn-active-border-color: #000000;
    --bs-btn-active-color: #47a2da;
    --bs-btn-disabled-bg: #000000;
    --bs-btn-disabled-border-color: #000000;
    --bs-btn-disabled-color: #8c97a1;
}

.bg-primary { background-color: #47a2da !important; }
.text-primary { color: #47a2da !important; }
.border-primary { border-color: #47a2da !important; }

/* Bootstrap dark/light/secondary/muted утиліти — переналаштовані під GRPhoto-палітру.
   Bootstrap дефолти: bg-dark/text-dark = #212529 (gray-900), bg-light = #f8f9fa,
   bg-secondary/text-muted = #6c757d. Це не наші бренд-токени — перекриваємо на pure black,
   #f1f2f4 і slate #8c97a1 відповідно. Перекриття діє глобально, бо ці класи рясно вживаються
   у Bootstrap-компонентах (.navbar.bg-dark, .badge.bg-secondary, .text-muted у списках тощо). */
.bg-dark { background-color: #000000 !important; }
.text-dark { color: #000000 !important; }
.border-dark { border-color: #000000 !important; }
.bg-light { background-color: #f1f2f4 !important; }
.bg-secondary { background-color: #8c97a1 !important; }
.text-muted { color: #8c97a1 !important; }
.text-secondary { color: #8c97a1 !important; }

/* btn-dark — той самий "dark CTA", що й btn-primary (чорний фон, sky-blue текст на hover).
   Унифікуємо — в системі лише одна форма "primary action" кнопки. */
.btn-dark {
    --bs-btn-bg: #000000;
    --bs-btn-border-color: #000000;
    --bs-btn-color: #f1f2f4;
    --bs-btn-hover-bg: #000000;
    --bs-btn-hover-border-color: #000000;
    --bs-btn-hover-color: #47a2da;
    --bs-btn-active-bg: #000000;
    --bs-btn-active-border-color: #000000;
    --bs-btn-active-color: #47a2da;
    --bs-btn-disabled-bg: #000000;
    --bs-btn-disabled-border-color: #000000;
    --bs-btn-disabled-color: #8c97a1;
}


h2 {
    font-weight: 600;
}

body {
    background-color: #f1f2f4;
    font-family: 'Google Sans', sans-serif;
    font-optical-sizing: auto;
    font-style: normal;
    font-variation-settings: "GRAD" 0;
    color: #000000;
}

/* Modals */

/* Усі модалки клієнтської частини — вертикально по центру (рівнозначно Bootstrap modal-dialog-centered, але без потреби додавати клас). */
.modal-dialog {
    display: flex;
    align-items: center;
    min-height: calc(100% - var(--bs-modal-margin, 1.75rem) * 2);
}

/* Темніший backdrop + легкий блур фону, щоб модалка відчувалась "піднятою" над сторінкою.
   Bootstrap робить напівпрозорість через `opacity` — це створює окремий stacking context
   і блур не пробиває до контенту нижче. Тому opacity елемента тримаємо 1, а напівпрозорість
   через rgba у background-color. */
.modal-backdrop {
    --bs-backdrop-opacity: 1;
    /* GRPhoto-палітра — чистий чорний, без синюватого відтінку */
    background-color: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(1px) saturate(0.5) contrast(0.8) brightness(0.95);
    -webkit-backdrop-filter: blur(1px) saturate(0.5) contrast(0.8) brightness(0.95);
}

.modal-content {
    border: none;
    background-color: #000000;
}

.modal-content form {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-height: calc(100vh - 3.5rem);
}

.modal-content form .modal-body {
    overflow-y: auto;
}

.modal-header {
    /* Sky-blue смуга: висота й типографіка — як смуга фільтрів під заголовком сторінки
       (.page-head-sub / .list-filter): min-height 48px, padding 0.6rem, 0.75rem/600 uppercase. */
    background-color: var(--gr-primary);
    color: #f1f2f4;
    min-height: 48px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    font-weight: 600;
    font-size: 0.75rem;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Хрест закриття не мусить дрібнішати разом зі зменшеним header-шрифтом — тримаємо зручний розмір. */
.modal-header .btn-close {
    font-size: 1rem;
}

.modal-header i {
    color: #8c97a1;
}

/* Cards */
.card {
    border: none;
    border-radius: 0.5rem;
    overflow: hidden;
}

.card-title {
    font-weight: 600;
}

.card-body,
.modal-body {
    padding: 1.6rem 1.8rem;
}

.card-header {
    background-color: #000000;
    color: #f1f2f4;
    font-weight: 400;
    padding-top: 1.05rem;
    padding-bottom: 0.95rem;
    text-transform: uppercase;
    font-size: 1.1rem;
    letter-spacing: 0.05em;
}

.card-header-mini {
    background-color: #000000;
    color: #f1f2f4;
    padding: 0.95rem 1.8rem 0.80rem;
    font-size: 0.75rem;
    line-height: 1;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border-bottom: 0;
}

/* Допоміжний контент справа в dark-хедері (Комерційне тощо) — приглушений,
   щоб не конкурував із номером */
.card-header-mini-right {
    color: var(--gr-gold);
    font-weight: 400;
}

.card-header-mini-right:empty {
    display: none;
}

.card-title-clickable {
    cursor: pointer;
    color: var(--bs-link-color);
    transition: color 0.15s ease;
}

.card-title-clickable:hover {
    color: var(--bs-link-hover-color);
}

/* Page header (grynykha-стиль) — повноширинна чорна смуга з великим h1,
   приклеєна до низу чорного навбару, а під нею світла смуга з фільтрами/дією.
   Рендериться партіалом client/_partials/page_header.html.twig. */
.page-head {
    background-color: #000000;
    padding: 3.5rem 0 2.3rem;
}
.page-head-title {
    margin: 0;
    color: #f1f2f4;
    font-weight: 700;
    line-height: 1;
    font-size: clamp(2.25rem, 5vw, 3.5rem);
}
/* Клікабельні заголовок/адреса об'єкта: дефолтний колір лишається (білий/slate),
   на hover — sky-blue. Застосовується на h1 та на обгортці адреси у чорному герої. */
.page-head-editable {
    cursor: pointer;
    transition: color 0.15s ease;
}
.page-head-editable:hover {
    color: var(--gr-primary);
}
/* Розділена навпіл смуга (дашборд): назва зліва, опис справа з вирівнюванням вправо. */
.page-head .container.page-head-split {
    display: flex;
    align-items: center;
    gap: 2rem;
}
.page-head-split .page-head-title {
    flex: 1 1 50%;
    min-width: 0;
}
.page-head-aside {
    flex: 1 1 50%;
    min-width: 0;
    text-align: right;
    color: #8c97a1;
    font-size: 1rem;
    line-height: 1.5;
}
@media (max-width: 767.98px) {
    .page-head .container.page-head-split {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.85rem;
    }
    .page-head-aside {
        flex-basis: auto;
        text-align: left;
    }
}
.page-head-sub {
    background-color: var(--gr-primary);
}
.page-head-sub > .container {
    min-height: 48px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    gap: 1rem;
}
/* Смуга фільтрів (фон кольору посилань, sky-blue): фільтр без верхнього відступу,
   неактивні підписи — світлі (slate на синьому не читається), активний — чорний. */
.page-head-sub .list-filter {
    margin-top: 0;
}
.page-head-sub .list-filter-item {
    color: #f1f2f4;
}
.page-head-sub .list-filter-item:hover,
.page-head-sub .list-filter-item:focus {
    color: #ffffff;
    text-decoration: none;
}
.page-head-sub .list-filter-item.active {
    color: #000000;
}
.page-head-actions {
    flex: none;
}
/* Кнопка дії у смузі — оформлена як таби зліва: білий текст, uppercase, той самий
   трекінг; фон/борд прибрано (текст-лінк з іконкою, а не «кнопка»). */
.page-head-action {
    background: transparent;
    border: 0;
    padding: 0;
    color: #f1f2f4;
    font-weight: 600;
    font-size: 0.75rem;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-decoration: none;
    cursor: pointer;
}
.page-head-action:hover,
.page-head-action:focus {
    color: #ffffff;
    text-decoration: none;
}
/* Білий лінк у смузі (напр. URL компанії на дашборді) — без uppercase і без підкреслення. */
.page-head-link {
    color: #f1f2f4;
    text-decoration: none;
    font-size: 0.85rem;
}
.page-head-link:hover,
.page-head-link:focus {
    color: #ffffff;
    text-decoration: none;
}

/* List filter — inline-рядок опцій під заголовком сторінки (заміна nav-tabs).
   Активна опція — колір заголовка + bold; решта — посилання; широкий gap замість роздільника. */
.list-filter {
    font-weight: 600;
    display: flex;
    flex-wrap: wrap;
    gap: 0.70rem;
    margin-top: 0.4rem;
    font-size: 0.75rem;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.list-filter-item {
    color: #8c97a1;
    text-decoration: none;
}

.list-filter-item:hover,
.list-filter-item:focus {
    color: #47a2da;
    text-decoration: underline;
}

.list-filter-item.active {
    color: #000000;
    /*font-weight: 700;*/
    cursor: default;
    text-decoration: none;
}

.card-header i,
.modal-header i {
    color: #8c97a1;
}

/* Section subheaders (like table thead) — slate-grey тон, легше за header.
   Чорні card-header'и вже домінують; section-subheader має бути «другим рівнем» сірого
   (не повторювати чорний). */
.section-subheader {
    background-color: #8c97a1;
    color: #f1f2f4;
    font-weight: normal;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.5rem 1rem;
    margin: 2.3rem 0 0;
}

.section-subheader:first-child {
    margin-top: 0.3rem;
}

/* Tables */
.table thead th {
    background-color: #8c97a1;
    color: #f1f2f4;
    font-weight: normal;
}

.table td:first-child,
.table th:first-child {
    padding-left: 1rem;
}

.table td:last-child,
.table th:last-child {
    padding-right: 1rem;
}

/* Бейджі клієнтської частини: менший радіус і тонший шрифт за дефолт Bootstrap. */
.badge {
    --bs-badge-border-radius: 0.2rem;
    --bs-badge-font-weight: 400;
}

.table .badge {
    font-weight: 400;
}

h1 {
    font-weight: 700;
}

/* Tooltip hint icon next to form labels */
.tooltip-hint {
    font-size: 0.7rem;
    color: #47a2da;
    cursor: help;
    vertical-align: middle;
    margin-left: 0.2rem;
    position: relative;
    top: -0.1em;
}

/* Cards & modals: white background, light grey borderless inputs */
.card-body,
.modal-body {
    background-color: #fff;
}

.card-footer {
    background-color: #e3e6e9;
    color: #000000;
    border-top: 0;
    padding: 0.75rem 1.8rem;
}

/* Грошова сума (макрос ui.money_compact): сума жирна, валюта нормальна — щоб око вело по числу. */
.money-amount {
    font-weight: 700;
}
.money-currency {
    font-weight: 400;
}

/* Префікси перед сумою/числом ("~", "+", "~+") — тонкі, того ж рівня що й валюта,
   щоб число лишалось акцентом. */
.amount-prefix {
    font-weight: 400;
}

/* Допоміжний підпис під цифрою у footer (наприклад «прогнозована · фіксована»).
   Стилізовано в дусі card-header-mini — uppercase, letter-spacing, приглушено. */
.price-meta {
    font-size: 0.7rem;
    line-height: 1;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #8c97a1;
    margin-top: 0.25rem;
}

.modal-footer {
    background-color: #e6e8ea;
}

/* Лейбли форм — у тому ж дусі, що card-мета (.price-meta): uppercase, slate,
   дрібний кегль із трекінгом. client.css вантажиться лише в клієнтській зоні
   й після Bootstrap, тож це накриває всі клієнтські форми (модалки, профіль,
   логін) і не чіпає адмінку. Чекбоксні підписи (.form-check-label) — навмисно
   лишаємо як є (це описовий текст біля галочки, а не польовий лейбл). */
.form-label {
    font-size: 0.7rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #8c97a1;
    font-weight: 400;
    margin-bottom: 0.35rem;
}

/* Нередаговане поле — значення просто текстом замість заблокованого інпута:
   напівжирне, чорне, основного кеглю. Висота/паддинг як в інпута, щоб поле в
   ряду з редагованими не «стрибало» по вертикалі. */
.form-static {
    font-weight: 600;
    color: #000000;
    min-height: calc(1.5em + 0.75rem + 2px);
    padding: 0.375rem 0;
    line-height: 1.5;
}
/* Порожнє значення (риска «—») — світло-сіре, як приглушений хрестик «ні». */
.form-static-empty {
    color: #d5d9dd;
}

/* Залочений булевий (чекбокс) — іконка-стан + лейбл в один рядок замість тексту
   «Так/Ні»: жирна чорна галочка (Так) / хрестик (Ні) перед лейблом. Монохром —
   у межах палітри (без зеленого/червоного). */
.form-static-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 1.5rem; /* як у Bootstrap .form-check — щоб пітч рядків збігався з редагованими чекбоксами */
}
/* Лише іконка-стан (галочка/хрестик) — чорна, трохи більша. tooltip-hint
   виключаємо, щоб «і» лишався дрібним синім, як у незалочених полях. */
.form-static-check i:not(.tooltip-hint) {
    color: #000000;
    font-size: 1.1rem;
    line-height: 1; /* щоб іконка не роздувала висоту рядка понад min-height 1.5rem */
}
/* Хрестик (стан «ні») — сірий: приглушений негативний стан (галочка лишається чорною). */
.form-static-check i.fa-xmark {
    color: #d5d9dd;
}

.form-control,
.form-select {
    border: none;
    background-color: #f1f2f4;
}

.form-control:focus,
.form-select:focus {
    background-color: #e6e8ea;
    box-shadow: none;
}

/* Locked (disabled/readonly) fields: темніший фон + приглушений текст */
.form-control:disabled,
.form-control[readonly],
.form-select:disabled,
.form-select[readonly] {
    background-color: #e6e8ea;
    color: #8c97a1;
    cursor: not-allowed;
    opacity: 1;
}

/* Disabled select — стрілка теж приглушена (slate-сіра, як у решти) */
.form-select:disabled {
    --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%238c97a1' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Залочений чекбокс + його лейбл */
.form-check-input:disabled,
.form-check-input[readonly] {
    cursor: not-allowed;
}
.form-check-input:disabled ~ .form-check-label,
.form-check-input[readonly] ~ .form-check-label {
    color: #8c97a1;
    cursor: not-allowed;
}

/* Placeholders */
::placeholder {
    color: #d5d9dd !important;
    opacity: 1;
}

/* Invoice badges in client cards */
.invoices-section .badge {
    font-size: 0.72rem;
    font-weight: 400 !important;
    padding: 0.3em 0.5em;
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

/* Invoice row highlight when navigated via #invoice-{id} anchor */
.invoices-table tbody tr {
    scroll-margin-top: 80px;
}
.invoices-table tbody tr:target {
    animation: invoiceHighlight 3s ease-out;
}
@keyframes invoiceHighlight {
    0%, 40% { background-color: #fff3cd; }
    100% { background-color: transparent; }
}

/* Compact tables inside order cards (invoices, sessions) */
.invoices-card-table > tbody > tr > td,
.sessions-card-table > tbody > tr > td {
    padding: 0.3rem 0.5rem;
    font-size: 0.85rem;
    vertical-align: middle;
    border: 0;
}
.invoices-card-table .shrink-col,
.sessions-card-table .shrink-col {
    width: 1px;
    white-space: nowrap;
}

/* Clickable table rows (handled by base.html.twig delegated click) */
.row-link {
    cursor: pointer;
}

/* ============================================================
   GRPhoto signature elements (для нових компонентів)
   ============================================================ */

/* Photo treatment — фото-плитки в галереях, превью обʼєктів зйомки тощо.
   GRPhoto-канон: rounded-1 (0.25rem), без рамок і тіней, object-fit: cover. */
.gr-photo {
    border-radius: 0.25rem;
    display: block;
    width: 100%;
    height: auto;
    object-fit: cover;
}

/* Breadcrumb signature — ▸ як роздільник.
   Використання:
     <nav class="gr-breadcrumb"><a>...</a><span class="sep"></span>...</nav> */
.gr-breadcrumb {
    font-size: 1.1rem;
    color: #8c97a1;
    padding: 0.7rem 0;
}
.gr-breadcrumb a { color: #8c97a1; text-decoration: none; }
.gr-breadcrumb a:hover { color: #47a2da; }
.gr-breadcrumb .sep::before {
    content: "▸";
    color: #d5d9dd;
    margin: 0 0.7rem;
}

/* GRPhoto тримає тінь тільки на навбарі. */
.client-navbar {
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* ============================================================
   Client shell — grynykha-стиль (шапка + offcanvas-меню + підвал)
   ============================================================ */

/* Sticky-footer каркас: підвал притиснутий до низу на коротких сторінках */
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
.main-content {
    flex: 1 0 auto;
    padding: 0 0 3rem;
}
/* Флеш-плашки між навбаром і шапкою сторінки: повноширинні, колір несе сама
   плашка (без скруглень і рамок), текст і хрестик у .container — на одній
   вертикалі з заголовком. Після закриття чорні смуги змикаються. */
.client-flash-bar {
    border: 0;
    border-radius: 0;
    margin: 0;
    padding: 0.875rem 0;
}
.client-flash-bar > .container {
    position: relative;
    padding-right: 2.5rem; /* текст не залазить під хрестик */
}
.client-flash-bar .btn-close {
    position: absolute;
    top: 50%;
    right: 0.75rem; /* правий край контенту контейнера */
    transform: translateY(-50%);
}

/* Контент під шапкою сторінки (page_header рендериться повноширинно над .container). */
.page-body {
    padding-top: 3rem;
}

/* Сторінки, увесь вміст яких живе в чорному герої (галерея об'єкта): світлої зони
   під ним немає взагалі, і 96px порожнього білого між героєм і підвалом читались
   як недороблена сторінка.

   Занулити padding було б замало: .main-content має flex:1 0 auto, тож на високому
   екрані порожнеча однаково розтяглася б. Тому міняємо не розмір, а колір — тло
   продовжує героя й зливається з чорним підвалом на будь-якій висоті. */
.main-content--flush {
    background-color: var(--gr-dark);
    padding-bottom: 0;
}
.main-content--flush .page-body {
    padding-top: 0;
}

/* --- Шапка --- */
.client-navbar {
    min-height: 60px;
}
.client-brand {
    display: inline-flex;
    align-items: center;
}
.client-logo {
    height: 24px;
    width: auto;
    fill: var(--gr-gold);
}
.client-wordmark {
    color: #f1f2f4;
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
}
/* На мобільному назва клієнта може бути довгою — прибираємо її з шапки
   (навігація лишається через бургер-меню). */
@media (max-width: 767.98px) {
    .client-brand {
        display: none;
    }
}
.client-burger {
    color: #47a2da;
    border: 0;
    padding: 0.25rem 0.5rem;
    font-size: 1.2rem;
    line-height: 1;
}
.client-burger:hover,
.client-burger:focus {
    color: #2789c5;
}
/* Індикатори справа в шапці: іконка як бургер (1.2rem), число як назва компанії (1.05rem). */
.client-navbar-stats {
    gap: 1.25rem;
}
/* Лічильник ліцензованих фото — голубий. */
.client-licensed {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #47a2da;
}
.client-licensed-ic {
    font-size: 1.2rem;        /* як бургер */
    line-height: 1;
}
.client-licensed-count {
    font-size: 1.05rem;       /* як назва компанії */
    font-weight: 600;
    line-height: 1;
}
/* Корзина ліцензій — sky-blue; посилання на сторінку корзини. Ховається коли порожня. */
.client-cart {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #47a2da;
    text-decoration: none;
}
.client-cart:hover,
.client-cart:focus {
    color: #2789c5;
}
.client-cart-ic {
    font-size: 1.2rem;        /* як бургер */
    line-height: 1;
}
.client-cart-count {
    font-size: 1.05rem;       /* як назва компанії */
    font-weight: 600;
    line-height: 1;
}
/* Борг по інвойсах — золотий (палітра не має червоного); посилання на активні інвойси. */
.client-due {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--gr-gold);
    text-decoration: none;
}
.client-due:hover,
.client-due:focus {
    color: var(--gr-gold);
    opacity: 0.8;
}
.client-due-ic {
    font-size: 1.2rem;        /* як бургер */
    line-height: 1;
}
.client-due-amounts {
    font-size: 1.05rem;       /* як назва компанії */
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}
.client-due-sep {
    margin: 0 0.35rem;
    opacity: 0.6;
}

/* --- Offcanvas-меню --- */
.client-menu {
    background-color: #fff;
    width: 320px;
    max-width: 85vw;
}
.client-menu .offcanvas-header {
    background-color: #f1f2f4;
    min-height: 60px;
    /* Вирівняти UK|EN під колонку іконок меню: nav padding (0.75) + link padding (0.9). */
    padding-left: 1.65rem;
}
.menu-lang a {
    color: #8c97a1;
    text-decoration: none;
    font-size: 0.8rem;
    letter-spacing: 0.05em;
}
.menu-lang .active {
    color: #000;
    font-weight: 600;
}
.menu-lang .sep {
    color: #d5d9dd;
    margin: 0 0.3rem;
}
.menu-nav {
    padding: 0.75rem;
}
/* Об'єкти клієнта — головні пункти меню: акцентовані (чорні, bold, більший кегль),
   над приглушеними slate-посиланнями навігації. Групу відмежовує відступ (без лінії). */
.menu-objects {
    margin-bottom: 0.85rem;
}
.menu-object {
    display: flex;
    align-items: center;
    border-radius: 0.5rem;
    padding: 0.5rem 0.9rem;
    color: #000;
    text-decoration: none;
    font-weight: 600;
    font-size: 1.05rem;
    line-height: 1.3;
    transition: color 0.15s ease;
}
.menu-object:hover,
.menu-object:focus {
    color: #47a2da;
}
.menu-object.active {
    background-color: #f1f2f4;
}
.menu-link {
    display: flex;
    align-items: center;
    border-radius: 0.5rem;
    padding: 0.6rem 0.9rem;
    margin-bottom: 0.1rem;
    color: #8c97a1;
    text-decoration: none;
    font-weight: 400;
    transition: color 0.15s ease;
}
.menu-link i {
    color: #8c97a1;
}
.menu-link:hover,
.menu-link:hover i {
    color: #47a2da;
}
.menu-link.active,
.menu-link.active i {
    color: #000;
    font-weight: 600;
    background-color: #f1f2f4;
}
.menu-link-danger,
.menu-link-danger i {
    color: var(--bs-danger);
}
.menu-link-danger:hover,
.menu-link-danger:hover i {
    color: var(--bs-danger);
}
.menu-account {
    background-color: #f1f2f4;
    padding: 0.75rem;
}
.menu-user {
    padding: 0.4rem 0.9rem 0.7rem;
}
.menu-user-name {
    font-weight: 600;
    color: #000;
}
.menu-user-email {
    font-size: 0.8rem;
    color: #8c97a1;
}
.menu-user-roles {
    margin-top: 0.35rem;
}

/* --- Підвал (тільки чорна смуга: контакти + перемикач мов) --- */
.client-footer {
    flex-shrink: 0;
}
.client-footer-bar {
    background-color: #000;
}
.client-footer-bar .container {
    min-height: 60px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
    gap: 1rem;
}
.cf-left {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-width: 0;
}
.cf-logo-link {
    display: inline-flex;
    flex: none;
}
.cf-contact-line {
    display: flex;
    align-items: center;
    column-gap: 0.85rem;
    min-width: 0;
    color: #8c97a1;
    font-size: 0.85rem;
}
.cf-contact-line .cf-author {
    color: #f1f2f4;
}
.cf-contact-line a {
    color: #8c97a1;
    text-decoration: none;
}
.cf-contact-line a:hover {
    color: #47a2da;
}

/* Вузький екран — три частини контактів стають стовпчиком */
@media (max-width: 767.98px) {
    .cf-contact-line {
        flex-direction: column;
        align-items: flex-start;
        column-gap: 0;
        row-gap: 0.1rem;
    }
}
.cf-lang {
    font-size: 0.85rem;
    white-space: nowrap;
}
.cf-lang a {
    color: #8c97a1;
    text-decoration: none;
}
.cf-lang .active {
    color: #f1f2f4;
    font-weight: 600;
}
.cf-lang .sep {
    color: #8c97a1;
    margin: 0 0.25rem;
}

/* Перемикач мови на світлих standalone-сторінках (login / forgot-password) */
.login-lang {
    font-size: 0.85rem;
    white-space: nowrap;
}
.login-lang a {
    color: #8c97a1;
    text-decoration: none;
}
.login-lang a:hover {
    color: #47a2da;
}
.login-lang .active {
    color: #000000;
    font-weight: 600;
}
.login-lang .sep {
    color: #d5d9dd;
    margin: 0 0.25rem;
}

/* ===== Галерея об'єкта (чорний герой) ===== */
.gallery-hero {
    background-color: var(--gr-dark);
    padding: 2rem 0 3rem;       /* верхній відступ під голубою смугою фільтрів */
}
.gallery-empty,
.gallery-empty-filter {
    color: var(--gr-secondary);
    text-align: center;
    padding: 3rem 0;
}
.gallery-divider {
    border-top: 1px solid var(--gr-divider);
    opacity: 0.25;
    margin: 0 0 1.5rem;
}

/* ===== Фільтри галереї — кастомні голубі дропдауни на смузі page-head-sub ===== */
.page-head-sub > .gallery-filterbar {
    gap: 1.75rem;
    /* Вертикальний padding нуль (замість 0.6rem зі спільного правила .container):
       активний фільтр малюється «табом» на всю висоту смуги, тож пункти мають
       діставати до її країв. Висоту тримає min-height, дропдауни центруються
       align-items: center на самій смузі. */
    padding-top: 0;
    padding-bottom: 0;
}
/* Фільтр стану — рядком просто на смузі: чотири пункти, зайвий клік не потрібен.
   На вузькому екрані вони не влізуть, тож там лишається дропдаун, а рядок ховається
   (та сама розмітка рендериться двічі з одного списку в шаблоні).
   margin-left: auto — стани праворуч, сесія лишається зліва (GR-0045). */
.gallery-filter-row { display: none; margin-left: auto; }
.gallery-dd--state { display: inline-flex; margin-left: auto; }

/* Обгортка дропдауна — теж flex, а не блок: інакше кнопка всередині лишається
   інлайновим боксом, сідає на базову лінію рядка й підпорядковується його
   struts'у, тобто вирівнюється не так, як сусідні пункти-фільтри, які є
   flex-елементами. Різниця виходила в пару пікселів і читалась як
   «кнопки трохи вище». */
.gallery-dd {
    display: inline-flex;
    align-items: center;
}

@media (min-width: 768px) {
    .gallery-filter-row {
        display: flex;
        /* stretch, не center: пункти тягнуться на всю висоту смуги, і плашка
           активного фільтра впирається в її краї (таб, а не чип). */
        align-self: stretch;
        align-items: stretch;
        gap: 1.25rem;
    }
    .gallery-dd--state { display: none; }
}

.gallery-filter-item {
    background: none;
    border: 0;
    /* Без вертикального padding і радіуса: пункт розтягнутий на всю висоту смуги
       (align-items: stretch у рядку), текст центрує flex — плашка активного
       виходить прямокутним табом від краю до краю смуги (GR-0045). */
    display: inline-flex;
    align-items: center;
    padding: 0 0.6rem;
    border-radius: 0;
    /* Приглушення — кольором, не opacity: прозорість елемента тягла б за собою
       й лічильник, а він має лишатись чорним на повну силу (GR-0046). */
    color: rgba(255, 255, 255, 0.8);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}
.gallery-filter-item:hover,
.gallery-filter-item:focus-visible { color: #ffffff; }
/* Активний пункт — суцільний білий таб (GR-0045) із чорним підписом. */
.gallery-filter-item.active {
    background: #ffffff;
    color: #000000;
}
/* Лічильник фото біля пункту фільтра — відділяється кольором (обрано Романом
   2026-08-16 замість «пігулки»): на голубій смузі підпис білий, а цифра чорна;
   на білому активному табі підпис чорний, а цифра — голуба в тон смуги. */
.gallery-filter-count {
    margin-left: 0.35rem;
    font-weight: 600;
    color: #000000;
}
.gallery-filter-item.active .gallery-filter-count {
    color: var(--gr-primary);
}

/* Тригер: текст-лінк у стилі фільтрів на смузі + шеврон вниз (без рамки/фону) */
.gallery-dd-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    background: none;
    border: 0;
    color: #000000;             /* обране значення — чорне, як активний фільтр на смузі */
    /* Той самий вертикальний габарит, що в .gallery-filter-item: контроли стоять
       поруч на одній смузі, тож коробка має бути однакова, а не просто схожа.
       По горизонталі нуль — «Усі сесії» лишається врівень із краєм контейнера. */
    padding: 0.3rem 0;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    cursor: pointer;
}
.gallery-dd-caret {
    font-size: 0.7em;
    transition: transform 0.15s ease;
}
.gallery-dd-toggle[aria-expanded="true"] .gallery-dd-caret {
    transform: rotate(180deg);
}
/* Меню — голубе в тон смуги, без рамки й тіні (per design system) */
.gallery-dd-menu {
    min-width: 9rem;
    margin-top: 0.5rem;
    padding: 0.3rem;
    background: var(--gr-primary);
    border: 0;
    border-radius: 0.45rem;
}
.gallery-dd-item {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    padding: 0.4rem 0.75rem;
    border-radius: 0.3rem;
    color: #f1f2f4;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
    cursor: pointer;
}
.gallery-dd-item:hover,
.gallery-dd-item:focus {
    background: rgba(255, 255, 255, 0.18);
    color: #ffffff;
}
.gallery-dd-item.active {
    background: rgba(255, 255, 255, 0.24);
    color: #ffffff;
    font-weight: 600;
}

/* Проміжок між колонкою фото і EXIF — ширший на десктопі (між g-3 і gx-5) */
@media (min-width: 992px) {
    .gallery-stage {
        --bs-gutter-x: 2rem;
    }
}

/* Рамка 3:2 — фон такий самий, як у чорного героя (.gallery-hero),
   щоб область фото зливалася з тлом слайдера. */
.gallery-frame {
    position: relative;
    aspect-ratio: 3 / 2;
    width: 100%;
    background-color: var(--gr-dark);
    border-radius: 0.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.gallery-frame img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
    cursor: zoom-in;           /* підказка: клік відкриває фото на весь екран */
}
/* Немає активного фото (порожній фільтр, або початковий src="" до ініціалізації
   Stimulus) — не показуємо ні «биту» картинку, ні залишковий alt-підпис. */
.gallery-frame img:not([src]),
.gallery-frame img[src=""] {
    display: none;
}
/* Чип «Чернетка» — поверх великого фото та в лайтбоксі. Світлий, у палітрі GRPhoto. */
.gallery-draft-chip {
    position: absolute;
    top: 0.6rem;
    left: 0.6rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    background: var(--gr-light);
    border: 1px solid var(--gr-divider);
    border-radius: 0.25rem;
    color: var(--gr-secondary);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    cursor: default;
}
.gallery-draft-chip[hidden] { display: none; }
.gallery-draft-chip--lightbox { top: 1rem; left: 1.25rem; z-index: 1090; }

/* Серце «улюблене» — правий верхній кут рамки (лівий зайнятий чипом «Чернетка»). */
.gallery-fav-btn {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
    background: rgba(24, 26, 27, 0.55);
    border: none;
    border-radius: 50%;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.95rem;
    cursor: pointer;
    transition: color 0.15s ease, background-color 0.15s ease;
}
.gallery-fav-btn:hover { background: rgba(24, 26, 27, 0.8); color: #ffffff; }
.gallery-fav-btn.is-fav { color: var(--gr-fav); }
.gallery-fav-btn:disabled { opacity: 0.6; cursor: default; }
.gallery-fav-btn[hidden] { display: none; }
/* У лайтбоксі — ліворуч від хрестика закриття (той на top:1rem/right:1.25rem). */
.gallery-fav-btn--lightbox { top: 1rem; right: 4.75rem; z-index: 1090; }

/* Нотатка про чернетку — у панелі деталей (на чорному герої). */
.gallery-draft-note {
    margin-top: 0.6rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(140, 151, 161, 0.4);   /* slate, приглушено */
    border-radius: 0.25rem;
    color: var(--gr-light);
    font-size: 0.76rem;
    line-height: 1.4;
}
.gallery-draft-note[hidden] { display: none; }
.gallery-caption {
    color: var(--gr-secondary);
    font-size: 0.8rem;
    text-align: center;
    padding-top: 0.7rem;
    min-height: 1.6rem;
}

/* EXIF-панель — 3 колонки справа від рамки (рамка — 9 колонок) */
.gallery-exif-col {
    display: flex;
    flex-direction: column;
}
.gallery-exif {
    color: var(--gr-light);
    font-size: 0.8rem;
}
.gallery-exif-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.4rem 0;
}
.gallery-exif-label {
    color: var(--gr-secondary);
    white-space: nowrap;
}
.gallery-exif-val {
    color: var(--gr-light);
    text-align: right;
    word-break: break-word;
}
.gallery-exif-empty {
    color: var(--gr-secondary);
    padding-top: 0.4rem;
}
/* ============ Блок дії в панелі об'єкта ============
   Один слот унизу EXIF-колонки, п'ять взаємовиключних станів.
   margin-top:auto притискає його до низу — врівень з низом великого фото. */
.gallery-action {
    margin-top: auto;
    padding-top: 1rem;
}
.gallery-action[hidden] { display: none; }

/* Головна дія — велика голуба кнопка на всю ширину панелі */
.ga-cta {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    width: 100%;
    padding: 0.8rem 0.85rem;
    border: 0;
    border-radius: 0.2rem;
    background: var(--gr-primary);
    /* Чорний, не білий: білий на #47a2da дає 2.8:1 при нормі 4.5:1, а дрібний
       другий рядок із opacity .82 — узагалі 2.4:1, тобто саме той текст, що має
       пояснювати, читався найгірше. Чорний дає 7.6:1, і рядок з тією ж
       прозорістю — ще ≈6:1, тож ієрархія лишається. Рішення Романа 2026-08-03. */
    color: var(--gr-dark);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s ease;
}
.ga-cta:hover,
.ga-cta:focus { background: #3b93c9; }
.ga-cta-ico { flex: 0 0 auto; font-size: 1.15rem; opacity: 0.95; }
.ga-cta-txt { flex: 1 1 auto; min-width: 0; }
.ga-cta-t1 {
    display: block;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.15;
}
.ga-cta-t2 {
    display: block;
    margin-top: 0.18rem;
    font-size: 0.69rem;
    line-height: 1.3;
    opacity: 0.82;
}
.ga-cta-price {
    flex: 0 0 auto;
    padding-left: 0.35rem;
    font-size: 1.06rem;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
/* Слот «дія тут буде, але поки недоступна» — габарит .ga-download, рамка пунктирна.
   Раніше причина недоступності була голим рядком тексту, і низ панелі стрибав
   при гортанні: у двох станів був блок на всю ширину, у двох — підпис у порожнечі. */
.ga-slot {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.68rem 0.85rem;
    border: 1px dashed #2f3439;   /* темніше за --gr-muted: рамка не має сперечатися з текстом */
    border-radius: 0.2rem;
    color: var(--gr-secondary);
    font-size: 0.72rem;
    line-height: 1.35;
    text-align: center;
}
.ga-slot[hidden] { display: none; }
.ga-slot i { opacity: 0.75; }

/* Стан «у кошику» — той самий габарит, але обведений замість залитого */
.ga-incart {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.72rem 0.85rem;
    border: 1px solid var(--gr-primary);
    border-radius: 0.2rem;
    color: var(--gr-light);
}
.ga-incart-chk { flex: 0 0 auto; color: var(--gr-primary); }
.ga-incart-t1 { flex: 1 1 auto; font-size: 0.9rem; font-weight: 600; }
.ga-incart-price {
    font-size: 0.94rem;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.ga-subacts {
    display: flex;
    justify-content: space-between;
    gap: 0.6rem;
    margin-top: 0.55rem;
}
.ga-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--bs-link-color);
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
}
.ga-link:hover,
.ga-link:focus { color: var(--bs-link-hover-color); }
.ga-link-mut { color: var(--gr-secondary); }

/* Придбане — тип ліцензії (gold) + скачування обведеною кнопкою (слабший акцент, ніж CTA) */
.ga-license {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.55rem;
    color: var(--gr-gold);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
/* Той самий рядок для стану «в обробці» — сірий, бо золоте лишається за придбаним. */
.ga-license--muted { color: var(--gr-secondary); }
.ga-download {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.68rem 0.85rem;
    border: 1px solid var(--gr-muted);
    border-radius: 0.2rem;
    background: transparent;
    color: var(--gr-light);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.15s ease;
}
.ga-download:hover,
.ga-download:focus { border-color: var(--gr-light); }
.ga-download[hidden] { display: none; }

/* «В процесі» — стан 5. Той самий габарит, що й .ga-download, але суцільна сіра
   рамка: це не дія, а статус. Пілюля тут була єдиною формою такого роду в панелі. */
.ga-status {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.68rem 0.85rem;
    border: 1px solid var(--gr-secondary);
    border-radius: 0.2rem;
    color: var(--gr-light);
    font-size: 0.78rem;
    font-weight: 600;
}

/* Стрічка мініатюр */
.gallery-thumbs {
    display: flex;
    gap: 0.55rem;
    overflow-x: auto;
    padding-bottom: 0.5rem;
    margin-top: 0.4rem;
    scrollbar-width: thin;                    /* Firefox */
    scrollbar-color: #2a2a2a var(--gr-dark);  /* повзунок / трек на чорному героєві */
}
.gallery-thumbs::-webkit-scrollbar {
    height: 10px;
}
.gallery-thumbs::-webkit-scrollbar-track {
    background: var(--gr-dark);
}
.gallery-thumbs::-webkit-scrollbar-thumb {
    background: #2a2a2a;
    border-radius: 5px;
}
.gallery-thumb {
    background: none;
    border: none;
    padding: 0;
    flex: 0 0 auto;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
}
.gallery-thumb.is-hidden { display: none; }
.gallery-thumb-square {
    position: relative;
    display: block;
    width: 92px;
    height: 92px;
    border: 4px solid transparent;
    border-radius: 0.25rem;
    overflow: hidden;
    box-sizing: border-box;
}
.gallery-thumb-square img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.gallery-thumb-square.is-licensed { border-color: var(--gr-gold); }
.gallery-thumb-square.is-incart { border-color: #ffffff; box-shadow: 0 0 0 1px var(--gr-divider, #d5d9dd); }
.gallery-thumb-square.is-pending { border-color: var(--gr-secondary); opacity: 0.9; }
/* Індикатор «улюблене» на мініатюрі — окремо від бейджа ліцензії (той під
   квадратом і зайнятий короною/нагородою/годинником).

   Тінь навмисно напрямлена й слабка. Рівномірне гало (0 0 2px) заповнювало
   виїмку зверху й вістря знизу, і на 11px гліф переставав читатись як серце —
   виходила пляма. */
.gallery-thumb-fav {
    position: absolute;
    top: 0.2rem;
    right: 0.2rem;
    color: var(--gr-fav);
    font-size: 0.8rem;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45));
}
.gallery-thumb-fav[hidden] { display: none; }
.gallery-thumb.is-active .gallery-thumb-square { border-color: var(--gr-primary); }
.gallery-thumb-badge {
    height: 1rem;
    line-height: 1;
    color: var(--gr-gold);
    font-size: 0.8rem;
}
.gallery-thumb-badge.is-pending { color: var(--gr-secondary); }

/* ===== Лайтбокс — активне фото на весь екран ===== */
body.is-lightbox-open { overflow: hidden; }
.gallery-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1080;                          /* над sticky-навбаром */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    background-color: rgba(0, 0, 0, 0.96);  /* майже чорне тло для перегляду */
}
.gallery-lightbox[hidden] { display: none; }   /* перекриває display:flex */
.gallery-lightbox-img {
    max-width: 95vw;
    max-height: 92vh;
    object-fit: contain;
    border-radius: 0.25rem;
    cursor: zoom-out;
}
/* Кнопки керування — slate-сірі, світлішають на hover (як іконки на чорному) */
.gallery-lightbox-close,
.gallery-lightbox-nav {
    position: absolute;
    background: none;
    border: 0;
    color: var(--gr-secondary);
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease;
}
.gallery-lightbox-close:hover,
.gallery-lightbox-close:focus,
.gallery-lightbox-nav:hover,
.gallery-lightbox-nav:focus { color: #f1f2f4; }
.gallery-lightbox-close {
    top: 1rem;
    right: 1.25rem;
    padding: 0.4rem;
    font-size: 1.6rem;
}
.gallery-lightbox-nav {
    top: 50%;
    transform: translateY(-50%);
    padding: 0.75rem;
    font-size: 1.8rem;
}
.gallery-lightbox-prev { left: 0.5rem; }
.gallery-lightbox-next { right: 0.5rem; }

/* Якір лінка з галереї на конкретну ліцензію — не ховати під sticky-навбаром */
[id^="license-"] { scroll-margin-top: 6rem; }

/* --- Дашборд: картки об'єктів (колаж + лічильники) --- */
.object-card-collage {
    display: grid;
    grid-template-columns: 2fr 1fr;
    grid-template-rows: repeat(2, 6rem);
    gap: 4px;
    padding: 4px;
}

.object-card-cover { grid-row: 1 / 3; }

/* 1 фото — одна велика плитка; 2 фото — обкладинка + одна на всю висоту. */
.object-card-collage.collage-1 { grid-template-columns: 1fr; }
.object-card-collage.collage-1 .object-card-tile { grid-row: 1 / 3; }
.object-card-collage.collage-2 .object-card-tile:not(.object-card-cover) { grid-row: 1 / 3; }

.object-card-tile {
    position: relative;
    overflow: hidden;
}

.object-card-tile .gr-photo { height: 100%; }

.object-card-more {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    color: #f1f2f4;
    font-weight: 500;
    border-radius: 0.25rem;
}

.object-card-empty {
    margin: 4px;
    height: calc(12rem + 4px);
    background: #e6e8ea;
    border-radius: 0.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    align-items: center;
    justify-content: center;
    color: #8c97a1;
}

.object-card-name {
    color: #000000;
    font-weight: 600;
    text-decoration: none;
}

.object-card-name:hover { color: #47a2da; }

.object-card-address {
    color: #8c97a1;
    font-size: 0.85rem;
    margin-top: 0.15rem;
}

.object-card-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    font-size: 0.85rem;
    color: #8c97a1;
}

.object-card-stat-cart.is-active { color: #47a2da; }
.object-card-stat-licensed.is-active { color: var(--gr-gold); }

/* ============ Корзина ліцензій — модалка #cartModal ============ */
.cart-table td { vertical-align: middle; }
/* Мініатюра фото + клік для лайтбокса */
.cart-thumb-btn {
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    background: none;
    line-height: 0;
    cursor: zoom-in;
}
.cart-thumb {
    width: 48px;
    height: 48px;
    object-fit: cover;
}
.cart-thumb-empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--gr-light);
    color: var(--gr-secondary);
}
.cart-photo-meta {
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.cart-photo-name {
    font-weight: 500;
    word-break: break-word;
}
.cart-photo-subject { font-size: 0.85rem; }
/* Кнопка видалення з кошика — slate, синіє на hover (без червоного, палітра GRPhoto) */
.cart-remove {
    padding: 0.25rem 0.4rem;
    border: 0;
    background: none;
    color: var(--gr-secondary);
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease;
}
.cart-remove:hover,
.cart-remove:focus { color: var(--gr-primary); }
.cart-remove:disabled { opacity: 0.5; cursor: default; }

/* Перемикач «Ексклюзив» у рядку кошика.
   Сірі відтінки нижче (#2c2c2c/#3a3a3a/#141414/#242424) — не з палітри вгорі
   файлу, вони підібрані саме під чорне тло .modal-content (background-color:
   #000000), а не для використання деінде. */
.cart-col-exc { width: 7rem; }
.cart-col-price { width: 6.5rem; }
.cart-switch {
    position: relative;
    display: inline-block;
    width: 38px;
    height: 21px;
    vertical-align: middle;
    cursor: pointer;
}
.cart-switch input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: inherit;
}
.cart-switch-track {
    position: absolute;
    inset: 0;
    border-radius: 20px;
    background: #2c2c2c;
    border: 1px solid #3a3a3a;
    transition: background 0.15s ease, border-color 0.15s ease;
    pointer-events: none;
}
.cart-switch-track::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--gr-secondary);
    transition: left 0.15s ease, background 0.15s ease;
}
.cart-switch input:checked + .cart-switch-track {
    background: var(--gr-primary);
    border-color: var(--gr-primary);
}
.cart-switch input:checked + .cart-switch-track::after {
    left: 20px;
    background: #ffffff;
}
.cart-switch input:focus-visible + .cart-switch-track {
    outline: 2px solid var(--gr-primary);
    outline-offset: 2px;
}
/* Запит у польоті (toggleExclusive чекає відповідь) — притлумлюємо трек як
   сигнал «зачекайте». Виключаємо .is-disabled: коли перемикач уже остаточно
   мертвий (ексклюзив розібрали), пріоритет має темніший стан нижче, не цей. */
.cart-switch:not(.is-disabled) input:disabled + .cart-switch-track {
    opacity: 0.6;
}
/* Ексклюзив уже неможливий — перемикач мертвий, під ним причина текстом.
   Не тултипом: на тачі тултип не відкривається. */
.cart-switch.is-disabled { cursor: default; }
.cart-switch.is-disabled .cart-switch-track {
    background: #141414;
    border-color: #242424;
}
.cart-switch.is-disabled .cart-switch-track::after { background: #3a3a3a; }
.cart-switch-hint {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.66rem;
    line-height: 1.3;
    color: var(--gr-muted);
}
.cart-price { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Групи по об'єкту (tbody на об'єкт). Заголовок групи — чекбокс «замовити
   цей об'єкт» + назва, праворуч підсумок групи. Знята позначка притлумлює
   рядки (.is-off): фото лишаються в кошику на потім, у POST не потрапляють. */
.cart-group-row th,
.cart-group-row td {
    padding-top: 0.85rem;
    padding-bottom: 0.45rem;
    border-bottom: 1px solid #3a3a3a;
}
.cart-group + .cart-group .cart-group-row th,
.cart-group + .cart-group .cart-group-row td { padding-top: 1.2rem; }
.cart-group-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    cursor: pointer;
}
.cart-group-toggle .form-check-input {
    flex: 0 0 auto;
    margin: 0;
    cursor: inherit;
}
/* Той самий ритм, що й підпис «Разом» нижче: дрібний uppercase із розрядкою */
.cart-group-name {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.cart-group-subtotal { font-weight: 600; }
.cart-group.is-off [data-cart-row] { opacity: 0.35; }
.cart-group.is-off .cart-group-subtotal {
    color: var(--gr-muted);
    text-decoration: line-through;
}
.cart-groups-hint {
    margin: 0.2rem 0 0;
    font-size: 0.8rem;
    color: var(--gr-muted);
}

/* Підсумок під таблицею — перед полем коментаря */
.cart-total {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 0.9rem;
    padding-top: 0.9rem;
}
.cart-total-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gr-secondary);
}
.cart-total-value {
    font-size: 1.35rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* Лайтбокс великого фото — поверх модалки (корзина + модалка ліцензії) */
.cart-lightbox,
.photo-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1090;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    background-color: rgba(0, 0, 0, 0.96);
    cursor: zoom-out;
}
.cart-lightbox[hidden],
.photo-lightbox[hidden] { display: none; }
.cart-lightbox img,
.photo-lightbox img {
    max-width: 95vw;
    max-height: 92vh;
    object-fit: contain;
    border-radius: 0.25rem;
}

/* Read-only список обраних фото в модалці ліцензії */
.license-photos-head {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--gr-secondary);
    margin-bottom: 0.5rem;
}
.license-photo-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.license-photo-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}
.license-free-badge { margin-left: auto; }

/* Ряд фото в модалці скачування — мініатюра + назва (клас cart-* спільні) */
.download-photo-row { cursor: pointer; }

/* Назва сесії в модалці скачування — клікабельна (toggle всіх фото сесії) */
.download-session-toggle {
    display: inline-block;
    background: none;
    border: 0;
    padding: 0;
    font-family: inherit;
    color: var(--gr-secondary);
    cursor: pointer;
    text-align: left;
}
.download-session-toggle:hover,
.download-session-toggle:focus { color: var(--gr-primary); }

/* ============ Картка замовлення фото (client/license/index) ============ */

/* Бейджі статусу — власні, не bootstrap-ні: `done` має бути золотим
   (той самий акцент, що на придбаних фото в галереї), а такого кольору
   в бутстрапі немає. Модифікатор = значення enum через дефіс. */
.order-badge {
    display: inline-block;
    padding: 0.28rem 0.6rem;
    border-radius: 0.2rem;
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1.2;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    background: var(--gr-light);
    color: var(--gr-muted);
}

.order-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Сервісний вимір */
.order-badge--draft       { background: var(--gr-light);   color: var(--gr-muted); }
.order-badge--confirmed   { background: #e3f1fa;           color: #1c5f88; }
.order-badge--in-progress { background: var(--gr-primary); color: #000000; }
.order-badge--completed   { background: #e6f4ea;           color: #1e6b38; }
/* Придбане — золоте, як рамка придбаного фото в галереї.
   Білий на #8c7a4a дає ≈4.6:1 — AA впритул. Освітлиш токен — завалиш контраст. */
.order-badge--done        { background: var(--gr-gold);    color: #ffffff; }
.order-badge--cancelled   { background: var(--gr-light);   color: var(--gr-muted); text-decoration: line-through; }

/* Платіжний вимір */
.order-badge--estimated      { background: var(--gr-light); color: var(--gr-muted); }
.order-badge--partially-paid { background: #fdf1dc;         color: #7a5310; }
.order-badge--paid           { background: #e6f4ea;         color: #1e6b38; }
.order-badge--overdue        { background: #fbe3e3;         color: #8a1c1c; }
.order-badge--gifted         { background: #e3f1fa;         color: #1c5f88; }
.order-badge--free           { background: #e6f4ea;         color: #1e6b38; }

/* Тип ліцензії — праворуч у шапці тіла картки, приглушено:
   він важливий (пояснює ціну), але не він відповідає на «що це». */
.order-type {
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--gr-secondary);
    white-space: nowrap;
}

/* Другий і наступні об'єкти під заголовком */
.order-subjects-more {
    font-size: 0.85rem;
    color: var(--gr-secondary);
}

/* Смуга мініатюр складу. Мініатюри тут НЕ клікабельні: картка це зведення,
   а лайтбокс живе в модалці, куди веде заголовок. Так на сторінці не
   з'являється по одному photo-zoom-контролеру й оверлею на кожну картку. */
.order-thumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.order-thumbs-more {
    font-size: 0.8rem;
    color: var(--gr-secondary);
    padding-left: 0.15rem;
}

/* Скасоване замовлення лишається в списку, але не претендує на увагу. */
.order-card--cancelled { opacity: 0.55; }
.order-card--cancelled:hover { opacity: 1; }
