/* Layout — app chrome shared by every page: global html/body, the email verification banner
   (base.html), sidebar / mobile bars / drawers / notification panel (partials/navbar.html).
   Moved out of the templates' <style> blocks on 2026-10-10 (docs/superpowers/plans/
   2026-10-10-seasonal-events.md). Colours go through tokens, so themes and seasonal looks
   (static/css/event-<slug>.css) recolour the chrome without per-page edits. */

/* Global overscroll/body background — matches the app theme */
html, body { background: var(--bg); margin: 0; }
/* Kill rubber-band overscroll so fixed mobile drawers (sitting just below
   the viewport) can't peek into view when scrolling past the page end. */
html, body { overscroll-behavior-y: none; }
/* Застосунок не масштабується пальцями — ні щипком, ні подвійним дотиком (Fiobs 2026-10-16; разом із viewport у base.html): гортання
   лишається, власні жести сторінок (свайпи, кулька, перетягування) задають свій touch-action на своїх елементах */
html { touch-action: pan-x pan-y; }

/* ── Email verification banner (authenticated, unverified) ── */
.ev-banner {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px;
    padding: 12px 20px;
    background: color-mix(in srgb, var(--accent) 8%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
    font-family: var(--font-sans); font-size: 13px; color: var(--text-secondary);
}
.ev-banner[hidden] { display: none; }
.ev-banner-text { flex: 1 1 240px; }
.ev-banner-text b { color: var(--text-primary); }
.ev-banner-form { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ev-banner-form input {
    width: 110px; padding: 7px 10px; border-radius: 8px;
    background: var(--bg); border: 1px solid var(--border);
    color: var(--text-primary); font-size: 15px; letter-spacing: 3px; text-align: center;
    font-family: var(--font-sans);
}
.ev-btn {
    padding: 7px 14px; border-radius: 8px; border: none; cursor: pointer;
    background: var(--accent); color: var(--text-on-accent); font-weight: 700; font-size: 13px;
    font-family: var(--font-sans);
}
.ev-btn-ghost { background: transparent; color: var(--accent); border: 1px solid var(--border-accent); }
.ev-btn:disabled { opacity: 0.5; cursor: default; }
.ev-banner-msg { flex-basis: 100%; font-size: 12px; color: var(--text-muted); }
.ev-banner-msg.ok { color: #4ADE80; }
.ev-banner-msg.err { color: #F87171; }

/* ── Plan strips above the page (partials/navbar.html; moved out of its <style> 2026-10-12) ──
   .hub-readonly — режим перегляду (Free); .hub-subwarn — «закінчується» / пільгові дні
   (SubscriptionService.ending_notice). Same look, one shape. */
.hub-readonly, .hub-subwarn {
    display: flex; align-items: center; justify-content: center;
    gap: 12px; flex-wrap: wrap;
    padding: 9px 16px;
    background: var(--warning-dim);
    border-bottom: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
    font-family: var(--font-sans);
    font-size: var(--text-caption); font-weight: 600;
    color: var(--text-primary);
}
.hub-readonly a, .hub-subwarn a { color: var(--warning); font-weight: 800; white-space: nowrap; text-decoration: none; }
.hub-readonly a:hover, .hub-subwarn a:hover { text-decoration: underline; }
.hub-readonly-preview { font-size: 0.68rem; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); }
/* Смужку можна закрити — до кінця дня або поки не зміниться її текст (Fiobs 2026-10-14: «на телефоні з'їдає купу місця
   й набридає»); пам'ятає браузер (navbar.html) */
.hub-readonly[data-notice], .hub-subwarn[data-notice] { position: relative; padding-right: 44px; }
.hub-readonly[hidden], .hub-subwarn[hidden] { display: none; }
.hub-notice-x {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; color: var(--text-muted);
    transition: color var(--transition), background-color var(--transition);
}
@media (hover: hover) { .hub-notice-x:hover { color: var(--text-primary); background: color-mix(in srgb, var(--warning) 14%, transparent); } }
.hub-notice-x svg { width: 14px; height: 14px; }

/* ==========================================================
   Chrome: sidebar (desktop) + bottom-nav (mobile) + drawers
   ========================================================== */

/* Body layout — content shifted right by sidebar on desktop, padded bottom by nav on mobile.
   Only on pages that include the chrome (auth, legal and the client portal don't). */
body:has(.hub-sidebar) { padding-left: 220px; }
/* Нижня панель (телефон): висота рядка пунктів, відступ пунктів від низу екрана, бокові поля всередині — тут, щоб
   сторінки, які ставлять щось над панеллю (липкі підсумки форм), брали --dock-space, а не числа */
:root { --dock-h: 64px; --dock-gap: 6px; --dock-pad: 24px; --dock-rise: 30px; }
/* Від низу екрана до рядка пунктів (панель під ним залита до самого низу): у браузері — малий відступ; у встановленому
   застосунку на iPhone — над смужкою «додому», але не на весь відступ, який система резервує під неї (34 px): там
   лишалась порожнеча (Fiobs 2026-10-14: «панель можна опустити нижче… у додатку там багато місця»). */
:root { --dock-bottom: max(var(--dock-gap), calc(env(safe-area-inset-bottom) - 14px)); }
:root { --dock-space: calc(var(--dock-h) + var(--dock-bottom)); }
@media (max-width: 768px) {
    body:has(.hub-sidebar) { padding-left: 0; padding-bottom: calc(var(--dock-space) + var(--dock-rise)); }
}

/* ── Sidebar (desktop, >768px) ────────────────────────── */
.hub-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 100;
    width: 220px;
    background: var(--surface);
    border-right: 1px solid var(--border);
    font-family: var(--font-sans);
    display: flex; flex-direction: column;
    overflow-y: auto;
}
@media (max-width: 768px) { .hub-sidebar { display: none; } }

.hub-sidebar-logo {
    display: block;
    padding: 20px var(--space-5);
    font-size: 1.1rem; font-weight: 800; letter-spacing: -0.02em;
    color: var(--text-primary); text-decoration: none;
    flex-shrink: 0;
}
.hub-sidebar-logo span { color: var(--accent); }

.hub-sidebar-nav {
    flex: 1;
    padding: 0 var(--space-3) var(--space-4);
    display: flex; flex-direction: column;
    gap: var(--space-1);
    overflow-y: auto;
}
.hub-sidebar-section {
    padding: var(--space-4) var(--space-3) var(--space-2);
    margin: 0;
    font-size: var(--text-label); font-weight: 700; letter-spacing: 0.1em;
    color: var(--text-muted); text-transform: uppercase;
}

.hub-sidebar-item {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    font-size: 0.88rem; font-weight: 600;
    color: var(--text-muted); text-decoration: none;
    border: 1px solid transparent;
    background: none; cursor: pointer; width: 100%;
    font-family: var(--font-sans); text-align: left;
    transition: color var(--transition), background-color var(--transition);
}
.hub-sidebar-item:hover { color: var(--text-primary); background: var(--surface-hover); }
.hub-sidebar-item.active {
    color: var(--accent);
    background: var(--accent-dim);
}
.hub-sidebar-item svg { flex-shrink: 0; width: 16px; height: 16px; }
/* Пінг (partials/ping.html) — найтонші кола, що розходяться й тануть (Fiobs 2026-10-19: «максимально тонкими»); розмір — --ping.
   Нове в Увазі дашборда — пінг від іконки дашборду в меню на будь-якій сторінці («не важливо, на якій ти сторінці вістуна, дашборд
   блимає, що є якась важлива звістка»); на дашборді його вмикає й вимикає сам дашборд */
.ping { position: absolute; left: 50%; top: 50%; z-index: 3; width: var(--ping, 48px); height: var(--ping, 48px); max-width: none; margin: calc(var(--ping, 48px) / -2) 0 0 calc(var(--ping, 48px) / -2); overflow: visible; pointer-events: none; fill: none; stroke: var(--warning); stroke-width: 0.5px; }   /* max-width — інакше base.css (svg ≤ 100%) стискає його до ширини крапки чи значка */
.ping[hidden] { display: none; }
.ping .ping-still { display: none; }
@media (prefers-reduced-motion: reduce) { .ping circle { display: none; } .ping .ping-still { display: inline; opacity: 0.7; } }
/* Пінг на іконці дашборду: обгортка — щоб правила іконок меню (розмір, колір, «> svg») його не чіпали; на дашборді в нижній панелі
   svg їде в кульку разом з іконкою (.hub-bottom-item.active svg) */
.hub-ping { position: absolute; left: 50%; top: 50%; z-index: 3; --ping: 44px; width: var(--ping); height: var(--ping); margin: calc(var(--ping) / -2) 0 0 calc(var(--ping) / -2); pointer-events: none; }
.hub-ping[hidden] { display: none; }
.hub-ping > svg.ping { position: static; display: block; width: 100%; height: 100%; margin: 0; }
.hub-bottom-item .hub-ping { --ping: 56px; }

/* Module colour comes from MODULE_CATALOG as --mod-color (tint 0x18 = 9.4 %) */
.hub-sidebar-mod-icon {
    background: color-mix(in srgb, var(--mod-color) 9.4%, transparent); color: var(--mod-color);
    width: 18px; height: 18px;
    border-radius: var(--radius-sm);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.hub-sidebar-mod-icon svg { width: 11px; height: 11px; }

.hub-sidebar-empty {
    padding: var(--space-2) var(--space-3);
    font-size: 0.72rem; color: var(--text-disabled);
    line-height: 1.4;
}

.hub-sidebar-add {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    margin-top: var(--space-1);
    border-radius: var(--radius-sm);
    font-size: 0.82rem; font-weight: 700; letter-spacing: 0.01em;
    color: var(--accent); background: var(--accent-dim);
    border: 1px solid transparent;
    font-family: var(--font-sans); cursor: pointer; width: 100%;
    text-align: left;
    transition: background-color var(--transition);
}
.hub-sidebar-add:hover { background: color-mix(in srgb, var(--accent) 18%, transparent); }
.hub-sidebar-add { text-decoration: none; }

.hub-sidebar-utility {
    padding: var(--space-3);
    border-top: 1px solid var(--border);
    display: flex; flex-direction: column; gap: var(--space-1);
    flex-shrink: 0;
}
/* Нижній рядок меню: версія, документи, контакти (sidebar — .hub-sidebar-meta, «Ще» — .hub-drawer-meta) */
.hub-sidebar-meta, .hub-drawer-meta {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
    padding: var(--space-2) var(--space-3) 0;
    font-family: var(--font-sans);
}
.hub-sidebar-meta a, .hub-drawer-meta a {
    font-size: 0.7rem; color: var(--text-muted); letter-spacing: 0.02em; text-decoration: none;
    transition: color var(--transition);
}
.hub-sidebar-meta a:hover, .hub-drawer-meta a:hover { color: var(--accent); }
.hub-drawer-meta { justify-content: center; padding: 10px 4px 0; border-top: 1px solid var(--border); margin-top: 10px; }
.hub-drawer-meta a { font-size: 0.78rem; }

/* ── Меню «Збоку» (обкатане на «Пульсі» 2026-10-12, для всіх — зі спринту 2026-10-13) ─────────────────
   Те саме меню (navbar.html) — base.html ставить body.nav-side: смужка іконок, при наведенні праворуч
   висувається панель з назвами. Пункт підсвічується цілим — одна підкладка (::before) під іконкою і назвою:
   у складеному меню вона обрізана до клітинки з іконкою, при розгортанні відкривається на весь пункт.
   Роздільники груп тягнуться на всю ширину розгорнутого меню. Анімується лише transform, opacity і clip-path.
   Назва пункту — span.hub-label, логотип — «V» + .hub-logo-rest. Вигляд «Зверху» прибрано («не зайшло»). */
.hub-sidebar-logo .hub-logo-rest { color: inherit; }
.hub-bell .hub-label { display: none; }
@media (min-width: 769px) {
    body.nav-side { --nav-ease: cubic-bezier(0.22, 1, 0.36, 1); }
    body.nav-side .hub-sidebar-empty, body.nav-side .hub-sidebar-meta,
    body.nav-side .hub-sidebar-section:first-child { display: none; }
    body.nav-side #sidebar-modules { display: contents; }
    body.nav-side .hub-bell .hub-label { display: block; }
    /* Пункт (і тема, і дзвіночок) — клітинка з іконкою; фон малює підкладка ::before */
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell) {
        position: relative; z-index: 1; margin: 0; padding: 0; gap: 0;
        justify-content: center; border: none; border-radius: 0; background: none;
    }
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell)::before {
        content: ""; position: absolute; z-index: -1; border-radius: 8px; background: transparent;
        transition: clip-path 0.26s var(--nav-ease), background-color 0.15s ease;
    }
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell):hover::before { background: var(--surface-hover); }
    body.nav-side .hub-sidebar-item.active::before { background: var(--accent-dim); }
    body.nav-side .hub-sidebar-item.active:hover::before { background: color-mix(in srgb, var(--accent) 18%, transparent); }
    /* Іконки — як у звичайному меню: пункти ядра приглушені, модулі — своїм кольором, «+» — акцентом */
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell) > svg { width: 18px; height: 18px; color: var(--text-muted); transition: color 0.15s ease; }
    body.nav-side :is(.hub-sidebar-item, .hub-bell):hover > svg { color: var(--text-primary); }
    body.nav-side .hub-sidebar-item.active > svg, body.nav-side .hub-sidebar-add > svg { color: var(--accent); }
    body.nav-side .hub-sidebar-mod-icon { width: 22px; height: 22px; }
    body.nav-side .hub-sidebar-mod-icon svg { width: 13px; height: 13px; }
    body.nav-side .hub-label {
        position: absolute; font-weight: 600; color: var(--text-secondary);
        opacity: 0; pointer-events: none; transition: opacity 0.18s ease, transform 0.24s var(--nav-ease);
    }
    body.nav-side .hub-sidebar-item.active .hub-label, body.nav-side .hub-sidebar-add .hub-label { color: var(--accent); }
    body.nav-side :is(.hub-sidebar-item, .hub-bell):hover .hub-label { color: var(--text-primary); }

    /* Смужка 56 px, при наведенні праворуч висувається ще 152 px з назвами — під найдовшу («Встановити
       застосунок», 145 px); назва — за 13 px від іконки, як у звичайному меню (Fiobs 2026-10-12: «надто
       широка… відступ від іконок величезний»). Підкладка розгорнутого меню (::after) — одна на смужку й
       панель: тінь падає лише назовні, шва між складеною і розгорнутою частинами немає (Fiobs: «чітко видно,
       де згорнута частина, а де розгорнута»). Складена — та сама підкладка, стиснута transform і прозора. */
    body.nav-side { --rail-w: 56px; --rail-panel: 152px; --rail-k: 0.2692; }  /* 56 / 208 */
    /* viewport-fit=cover (base.html): iPhone у ландшафті — смужка не ховається під виріз */
    body.nav-side:has(.hub-sidebar) { padding-left: calc(var(--rail-w) + env(safe-area-inset-left)); padding-right: env(safe-area-inset-right); }
    body.nav-side .hub-sidebar { left: env(safe-area-inset-left); width: var(--rail-w); overflow: visible; }
    body.nav-side .hub-sidebar::after {
        content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: calc(var(--rail-w) + var(--rail-panel)); z-index: 0;
        background: var(--surface); border-right: 1px solid var(--border); box-shadow: 14px 0 28px rgba(0, 0, 0, 0.28);
        transform: scaleX(var(--rail-k)); transform-origin: left; opacity: 0; pointer-events: none;
        transition: transform 0.26s var(--nav-ease), opacity 0.2s ease;
    }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open)::after { transform: none; opacity: 1; pointer-events: auto; }
    body.nav-side .hub-sidebar-head { position: relative; z-index: 1; flex-direction: column; align-items: center; gap: 2px; padding: 10px 0 8px; }
    body.nav-side .hub-sidebar-head .hub-sidebar-logo { align-self: stretch; margin: 0; padding: 2px 0 8px 22px; font-size: 1.15rem; white-space: nowrap; }
    body.nav-side .hub-logo-rest { opacity: 0; transition: opacity 0.18s ease; }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open) .hub-logo-rest { opacity: 1; transition-delay: 0.05s; }
    body.nav-side .hub-sidebar-nav, body.nav-side .hub-sidebar-utility {
        position: relative; z-index: 1; flex: 0 0 auto; align-items: center; gap: 2px;
        padding: 7px 0; border: none; overflow: visible;
    }
    body.nav-side .hub-sidebar-utility { margin-top: auto; }
    /* Пункти під шапкою гортаються, коли не вміщаються (низький екран, нові пункти — сторінка свята; Fiobs 2026-10-18: «може просто
       прокрутку додати?»): шапка з лого, темою й дзвіночком стоїть. Обгортка — завширшки зі смужку, а в розгорнутому меню — з усю панель,
       щоб назви не обрізались; звужується вже після того, як назви згасли (крок із затримкою, не анімація). Смуги прокрутки немає —
       край, за яким ще є пункти, тане (.is-more-top / .is-more-bottom ставить navbar.html). */
    body.nav-side .hub-sidebar-scroll {
        position: relative; z-index: 1; flex: 1; min-height: 0; display: flex; flex-direction: column;
        width: var(--rail-w); overflow: hidden auto; overscroll-behavior: contain; scrollbar-width: none;
        transition: width 0s linear 0.26s;
    }
    body.nav-side .hub-sidebar-scroll::-webkit-scrollbar { display: none; }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open) .hub-sidebar-scroll { width: calc(var(--rail-w) + var(--rail-panel)); transition-delay: 0s; }
    body.nav-side .hub-sidebar-scroll > :is(.hub-sidebar-nav, .hub-sidebar-utility) { width: var(--rail-w); }
    body.nav-side .hub-sidebar-scroll.is-more-bottom { mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent); }
    body.nav-side .hub-sidebar-scroll.is-more-top { mask-image: linear-gradient(to bottom, transparent, #000 28px); }
    body.nav-side .hub-sidebar-scroll.is-more-top.is-more-bottom { mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 28px), transparent); }
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell) { width: 40px; height: 32px; }
    body.nav-side :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell)::before {
        top: 0; bottom: 0; left: -2px; width: calc(var(--rail-w) + var(--rail-panel) - 12px);
        clip-path: inset(0 calc(100% - 44px) 0 0 round 8px);
    }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open) :is(.hub-sidebar-item, .hub-sidebar-add, .hub-bell)::before { clip-path: inset(0 round 8px); }
    body.nav-side .hub-label { left: calc(100% + 2px); top: 50%; white-space: nowrap; font-size: 13px; transform: translate(-6px, -50%); }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open) .hub-label { opacity: 1; transform: translate(0, -50%); transition-delay: 0.05s; }
    /* Роздільники груп — горизонтальні, на всю ширину розгорнутого меню */
    body.nav-side :is(.hub-sidebar-nav, .hub-sidebar-utility)::before, body.nav-side .hub-sidebar-section::before {
        content: ""; position: absolute; left: 0; top: 0; height: 1px; width: calc(var(--rail-w) + var(--rail-panel));
        background: var(--border); transform: scaleX(var(--rail-k)); transform-origin: left;
        transition: transform 0.26s var(--nav-ease);
    }
    body.nav-side .hub-sidebar:is(:hover, :focus-within, .is-open) :is(.hub-sidebar-nav, .hub-sidebar-utility, .hub-sidebar-section)::before { transform: none; }
    body.nav-side .hub-sidebar-section { position: relative; align-self: stretch; height: 1px; margin: 5px 0; padding: 0; font-size: 0; color: transparent; }
    body.nav-side .hub-sidebar-section::before { top: 0; }
    /* Сповіщення відкриті — меню лишається розгорнутим (Fiobs 2026-10-13: «я б не згортав її на нотифікаціях»),
       панель стоїть праворуч від нього */
    body.nav-side .notif-panel { top: 8px; left: calc(var(--rail-w) + var(--rail-panel) + 8px); }
    body.nav-side .hub-sidebar.is-open { z-index: 115; }  /* над затемненням сповіщень — пункти меню лишаються під рукою */
}
/* Низький екран — уся смужка не вміщається: два рідкісні пункти ховаються */
@media (min-width: 769px) and (max-height: 760px) {
    body.nav-side .hub-sidebar .js-install-link, body.nav-side .hub-sidebar-utility button[onclick*="CoachMarks"] { display: none; }
}
@media (min-width: 769px) and (prefers-reduced-motion: reduce) {
    body.nav-side .hub-sidebar *, body.nav-side .hub-sidebar *::before, body.nav-side .hub-sidebar::after { transition: none !important; }
}
/* ── Theme toggle (KAN-4): icon + label switch purely via [data-theme] ── */
.js-theme-toggle .th-ic-sun,
.js-theme-toggle .th-label-dark { display: none; }
[data-theme="light"] .js-theme-toggle .th-ic-moon,
[data-theme="light"] .js-theme-toggle .th-label-light { display: none; }
[data-theme="light"] .js-theme-toggle .th-ic-sun { display: block; }
[data-theme="light"] .js-theme-toggle .th-label-dark { display: inline; }
/* Theme wave (Fiobs 2026-10-09): View Transitions API + clip-path circle from the
   button. Dark → light: the new screen grows out of the button; light → dark: the
   old screen collapses back into it. The classes live on <html> only while a
   theme switch runs, so other view transitions keep their default cross-fade. */
html.theme-vt::view-transition-old(root),
html.theme-vt::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
/* Рамка має імена для переходів між сторінками (нижче) — на час «хвилі» теми вона частина кореня, інакше хвиля її оминала б */
html.theme-vt :is(.hub-sidebar, .hub-topbar, .hub-bottom-nav, .hub-dock-bead, .hub-bottom-item > svg) { view-transition-name: none !important; }
html.theme-vt-grow::view-transition-new(root) { animation: hub-theme-grow 0.6s cubic-bezier(0.22, 1, 0.36, 1) both; }
html.theme-vt-shrink::view-transition-old(root) { animation: hub-theme-shrink 0.6s cubic-bezier(0.55, 0, 0.8, 0.4) both; z-index: 1; }
html.theme-vt-shrink::view-transition-new(root) { z-index: 0; }
@keyframes hub-theme-grow {
    from { clip-path: circle(0 at var(--vt-x) var(--vt-y)); }
    to   { clip-path: circle(var(--vt-r) at var(--vt-x) var(--vt-y)); }
}
@keyframes hub-theme-shrink {
    from { clip-path: circle(var(--vt-r) at var(--vt-x) var(--vt-y)); }
    to   { clip-path: circle(0 at var(--vt-x) var(--vt-y)); }
}

/* ── Нижня панель (телефон, ≤768px; спринт 2026-10-13, за скріном Fiobs) ─────────────────
   Панель на всю ширину і до самого низу екрана, із заокругленим верхом (2026-10-14, Fiobs: «не островом унизу…
   бентежить мікропростір знизу та по сторонах»; до того — капсула, що «плавала» над смужкою iPhone); рядок пунктів —
   на --dock-bottom над низом екрана, під ним — та сама заливка. Активний пункт — кулька кольору акценту, що виступає
   над панеллю; край панелі обтікає її — .hub-dock-skin: SVG «виступу» з плечима, дотичними до краю (заливка
   ховає рамку панелі під виступом, лінія малює її по дузі). Кулька й виступ — одна обгортка .hub-dock-bead
   шириною в пункт: слот (data-slot) зсуває її translateX на N ширин — ні розкладки, ні перерахунку шляху.
   Іконка активного пункту піднімається в кульку, підпис з'являється під нею. Поля --dock-pad не дають виступу
   крайніх пунктів зайти на заокруглені кути. Кольори — токени панелі, тож свято перефарбовує й кульку. */
.hub-bottom-nav {
    display: none;
    position: fixed; z-index: 100;
    left: 0; right: 0; bottom: 0;
    height: var(--dock-space); box-sizing: border-box;
    padding: 0 var(--dock-pad) var(--dock-bottom);
    /* на тон світліша за картки — інакше виступ зливається з карткою під ним; свято перевизначає --surface на самій панелі */
    --surface: var(--surface-raised);
    background: var(--surface);
    /* рамка лише згори; нижня — прозора, щоб рядок пунктів мав ту саму висоту, що й у капсули (іконка в кульці — від неї) */
    border: 1px solid var(--border-strong); border-width: 1px 0; border-bottom-color: transparent;
    border-radius: 20px 20px 0 0;
    font-family: var(--font-sans);
    --dock-i: 0;
    /* верхні кути при закритті шторки заокруглюються одразу (шторка ховається під заокруглену панель), рамка проявляється плавно;
       transform — повне меню піднімає панель */
    transition: border-color var(--motion-fast) ease, transform var(--motion) var(--motion-ease);
}
@media (max-width: 768px) { .hub-bottom-nav { display: flex; } }
/* Палець веде кульку (navbar.html): поки веде — кулька йде за пальцем без затримки й трохи більшає;
   панель не віддає жест прокрутці сторінки */
.hub-bottom-nav { touch-action: none; }
.hub-bottom-nav.is-scrub .hub-dock-bead { transition: none; }
.hub-dock-ball { transition: transform var(--motion-fast) var(--motion-ease); }
.hub-bottom-nav.is-scrub .hub-dock-ball { transform: scale(1.08); }
/* Шторка відкрита — панель над затемненням, щоб її пункти лишались під пальцем */
body.hub-drawer-on .hub-bottom-nav { z-index: 201; }
/* Кулька — за місцем пункту (data-pos), а не за назвою: два місця обабіч дашборда кожен заповнює сам (navbar.html).
   «Ще» · свій · Дашборд · свій · «Модулі» (Fiobs 2026-10-15: дашборд по центру, шторки — по краях); «Ще» — нульовий */
.hub-bottom-nav[data-pos="1"] { --dock-i: 1; }
.hub-bottom-nav[data-pos="2"] { --dock-i: 2; }
.hub-bottom-nav[data-pos="3"] { --dock-i: 3; }
.hub-bottom-nav[data-pos="4"] { --dock-i: 4; }

.hub-dock-bead {
    position: absolute; z-index: 1; pointer-events: none;
    top: calc(-1 * var(--dock-rise)); left: var(--dock-pad);
    width: calc((100% - 2 * var(--dock-pad)) / 5); height: calc(var(--dock-rise) + 2px);
    transform: translateX(calc(var(--dock-i) * 100%));
    transition: transform var(--motion-slow) var(--motion-ease);
}
.hub-dock-skin { position: absolute; top: 0; left: calc(50% - 38px); max-width: none; overflow: visible; transform-origin: 50% 100%; }
/* шторка відкрита — капсула й шторка одна поверхня, виступ зайвий: кулька просто лежить на ній */
.hub-dock-skin { transition: opacity var(--motion-fast) ease; }
body.hub-drawer-joined .hub-dock-skin { opacity: 0; }
.hub-dock-skin-fill { fill: var(--surface); }
.hub-dock-skin-line { fill: none; stroke: var(--border-strong); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* Кулька — центр на краю панелі (рамка — 0,5 px над ним); тінь статична, анімується лише transform */
.hub-dock-ball {
    position: absolute; top: calc(var(--dock-rise) - 0.5px - 23px); left: calc(50% - 23px);
    width: 46px; height: 46px; border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 8px 18px color-mix(in srgb, var(--accent) 34%, transparent);
}

.hub-bottom-item {
    position: relative; z-index: 2;
    flex: 1; min-width: 0;
    display: flex; align-items: center; justify-content: center;
    padding: 0; background: none; border: none; cursor: pointer;
    color: var(--text-muted); text-decoration: none;
    font-family: var(--font-sans);
    -webkit-tap-highlight-color: transparent;
}
.hub-bottom-item svg {
    width: 22px; height: 22px;
    transition: transform var(--motion-slow) var(--motion-ease), color var(--motion-fast) ease;
}
@media (hover: hover) { .hub-bottom-item:hover { color: var(--text-primary); } }
/* Іконка активного пункту — у кульці: центр пункту (31 px під краєм) → край панелі */
.hub-bottom-item.active svg { color: var(--text-on-accent); transform: translateY(-31.5px); }
.hub-bottom-label {
    position: absolute; left: 0; right: 0; bottom: 8px;
    font-size: 0.66rem; font-weight: 800; letter-spacing: 0.02em; text-align: center; white-space: nowrap;
    color: var(--accent);
    opacity: 0; transform: translateY(5px);
    transition: opacity var(--motion-fast) ease, transform var(--motion) var(--motion-ease);
}
.hub-bottom-item.active .hub-bottom-label { opacity: 1; transform: none; transition-delay: 0.12s; }
@media (prefers-reduced-motion: reduce) {
    .hub-dock-bead, .hub-bottom-item svg, .hub-bottom-label { transition: none; }
}

/* ── Продовження нижньої панелі на сторінці (.hub-ext, телефон): рядок кнопок сторінки стоїть на панелі одним цілим —
   дашборд (тринадцяте коло, Fiobs: «наче для дашборду layout подовжується й на нього додаються кнопки»), клієнти. Угорі —
   період (.hub-ext-pill), перемикачі сторінки, на якій стоїш (.hub-ext-view[data-for] з .is-on — Board.pager), «+» (.hub-ext-plus);
   нижче, у смузі, де лежить кулька, — крапки сторінок (.hub-ext-dots). За рядок тягнуть угору повне меню (data-hub-pull). ── */
:root { --hub-ext-h: 82px; }
.hub-ext { display: none; }
@media (max-width: 768px) {
    body:has(.hub-ext:not(.is-off)) { padding-bottom: calc(var(--dock-space) + var(--hub-ext-h) + 6px); }
    .hub-ext {
        position: fixed; z-index: 99; left: 0; right: 0; bottom: calc(var(--dock-space) - 1px);
        height: var(--hub-ext-h); box-sizing: border-box; display: flex; flex-direction: column; padding: 10px 12px 0;
        --surface: var(--surface-raised); background: var(--surface);   /* той самий тон, що й панель; свято перевизначає обидва */
        border: 1px solid var(--border-strong); border-width: 1px 0 0; border-radius: 22px 22px 0 0;
        touch-action: none;   /* рядок — частина панелі: браузер не гортає під пальцем, рух угору — повне меню */
        transition: border-color var(--motion-fast) ease, transform var(--motion) var(--motion-ease);
    }
    /* панель під ним — без верхньої рамки й заокруглення: одна поверхня */
    body:has(.hub-ext:not(.is-off)) .hub-bottom-nav { border-top-color: transparent; border-top-left-radius: 0; border-top-right-radius: 0; }
    /* Межа «кнопки сторінки · основне меню» (Fiobs 2026-10-14: «міні уявна лінія… щоб було видно, що саме додалося»): тонка
       лінія по краю панелі, що тане до боків; кульку обтікає виступ .hub-dock-skin — він живе в кульці, тож дуга їде разом із нею */
    body:has(.hub-ext:not(.is-off)) .hub-bottom-nav::before {
        content: ''; position: absolute; top: -1px; left: 14px; right: 14px; height: 1px; pointer-events: none;
        background: var(--border-strong);
        mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent);
    }
    body:has(.hub-ext:not(.is-off)) .hub-bottom-nav .hub-dock-skin { opacity: 1; }
    /* шторки виїжджають з-за рядка: стос «шторка · рядок · панель» — одне меню */
    body:has(.hub-ext:not(.is-off)) .hub-drawer-clip { bottom: calc(var(--dock-space) + var(--hub-ext-h) - 22px); height: 46dvh; }
    body.hub-drawer-on .hub-ext { z-index: 201; }
    body.hub-drawer-joined .hub-ext { border-top-color: transparent; border-top-left-radius: 0; border-top-right-radius: 0; }
    body.hub-drawer-on:has(.hub-ext:not(.is-off)) .hub-bottom-nav { z-index: 202; }
    .hub-ext-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px; }
    .hub-ext-dots { flex: 1; display: flex; justify-content: center; align-items: center; transition: transform var(--motion) var(--motion-ease); }
    /* Крапки — у смузі, де лежить кулька панелі; там, де кулька їм заважає (Fiobs 2026-10-14: «для оплат анімація панелі буде
       перекривати крапки»), вони відходять у ширшу вільну частину смуги. Зсув — від центру: виступ кульки — ±37 px навколо
       центру пункту; пункт = (ширина − 2×--dock-pad) / 5. Друге місце й дашборд (центр) — праворуч, четверте — ліворуч;
       крайні «Ще» і «Модулі» крапкам не заважають. Шторки «Модулі»/«Ще» ведуть кульку — крапки їдуть за нею. */
    body:has(.hub-bottom-nav[data-pos="1"]) .hub-ext-dots { transform: translateX(calc(30.5px + 0.15 * (100vw - 2 * var(--dock-pad)))); }
    body:has(.hub-bottom-nav[data-pos="2"]) .hub-ext-dots { transform: translateX(calc(30.5px + 0.25 * (100vw - 2 * var(--dock-pad)))); }
    body:has(.hub-bottom-nav[data-pos="3"]) .hub-ext-dots { transform: translateX(calc(-30.5px - 0.15 * (100vw - 2 * var(--dock-pad)))); }
    .hub-ext-dots button { width: 22px; height: 22px; padding: 0; border: 0; background: none; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
    .hub-ext-dots button::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--border-strong); transition: transform 0.25s var(--motion-ease), background-color 0.25s ease; }
    .hub-ext-dots button.is-on::before { background: var(--text-secondary); transform: scale(1.35); }
    /* ширина стала — «Сьогодні», «Вер. 2025» чи «III кв. 2025» не міняють розкладку рядка; без чорного фону — поверхня рядка */
    .hub-ext-pill {
        width: 124px; justify-content: space-between;
        display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px; box-sizing: border-box;
        border-radius: var(--radius-pill); border: 1px solid var(--border-strong); background: none;
        color: var(--text-primary); font: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; white-space: nowrap;
    }
    .hub-ext-pill svg { width: 12px; height: 12px; flex-shrink: 0; color: var(--text-muted); transition: transform 0.25s var(--motion-ease); }
    .hub-ext-pill[aria-expanded="true"] svg { transform: rotate(180deg); }
    .hub-ext-pill span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
    .hub-ext-plus {
        width: 38px; height: 38px; padding: 0; border: 0; border-radius: 50%; cursor: pointer; text-decoration: none;
        display: inline-flex; align-items: center; justify-content: center;
        background: var(--accent); color: var(--text-on-accent); transition: transform 0.2s var(--motion-ease);
    }
    .hub-ext-plus svg { display: block; width: 20px; height: 20px; }
    .hub-ext-plus:active { transform: scale(0.93); }
    .hub-ext-views { display: grid; min-width: 0; }
    .hub-ext-view {
        grid-area: 1 / 1; justify-self: center; display: flex; align-items: center; gap: 8px; min-width: 0;
        opacity: 0; visibility: hidden; transform: translateY(4px);
        transition: opacity 0.22s ease, transform 0.3s var(--motion-ease), visibility 0s linear 0.3s;
    }
    .hub-ext-view.is-on { opacity: 1; visibility: visible; transform: none; transition: opacity 0.22s ease 0.05s, transform 0.3s var(--motion-ease), visibility 0s; }
    /* Сторінка зі списком розділів («Бізнес», «Модулі», DESIGN §9) і вкладки модуля: рядок з'являється, лише коли є що зробити, —
       назва розділу ліворуч, головна дія праворуч (.hub-ext-btn, «+»). Кнопки «‹ Назад» немає (Fiobs 2026-10-16: «усі будуть просто
       свайпати вправо… як в усіх додатках»): назад — свайп убік будь-де (Board.drill, Board.swipeBack). Без дії рядок під панеллю. */
    .hub-ext.is-off { visibility: hidden; transform: translateY(calc(100% + var(--dock-rise))); transition: transform var(--motion) var(--motion-ease), visibility 0s linear var(--motion); }
    .hub-ext-title { grid-column: 1 / 3; justify-self: start; min-width: 0; padding-left: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; font-weight: 700; color: var(--text-primary); }
    .hub-ext-btn {
        display: inline-flex; align-items: center; justify-content: center; height: 36px; padding: 0 16px; box-sizing: border-box;
        border: 0; border-radius: var(--radius-pill); background: var(--accent); color: var(--text-on-accent);
        font: inherit; font-size: 13.5px; font-weight: 800; text-decoration: none; cursor: pointer; white-space: nowrap;
        transition: transform 0.2s var(--motion-ease), opacity 0.2s ease;
    }
    .hub-ext-btn:active { transform: scale(0.96); }
    /* Перемикач сторінок із назвами (Board.swipePages: «Тарифи · Підписка · Карби», «Що нового») — посередині рядка, заливка їде
       за пальцем і за сторінкою; без чорного фону — поверхня рядка */
    .hub-ext-seg { grid-column: 1 / -1; justify-self: center; max-width: 100%; background: none; border-color: color-mix(in srgb, var(--accent) 30%, var(--border-strong)); }
    .hub-ext-seg button { min-height: 34px; padding: 0 16px; font-size: 14px; font-weight: 700; white-space: nowrap; }
    .hub-ext-seg .pl-seg-ind { top: 2px; bottom: 2px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--accent) 20%, transparent); }
    .hub-ext-btn:disabled { opacity: 0.5; }
    .hub-ext-btn[hidden] { display: none; }
    /* Поки відкрита клавіатура — панель і рядок сторінки під екраном (Board.typing): інакше на iPhone вони «їдуть» над клавіатурою */
    body.is-typing .hub-bottom-nav { transform: translateY(calc(100% + var(--dock-rise) + 8px)); }
    body.is-typing .hub-ext { transform: translateY(calc(100% + var(--dock-space) + var(--dock-rise) + 8px)); }
}
@media (prefers-reduced-motion: reduce) { .hub-ext-dots button::before { transition: none; } .hub-ext.is-off { transition: none; } }

/* ── «?» у верхній панелі телефона → що означають цифри сторінки, на якій стоїш: на весь екран, згори, як сповіщення
   (Fiobs 2026-10-14). Кнопка .hub-help-btn переноситься скриптом сторінки в .hub-topbar; деінде й на ПК — схована. ── */
.hub-bell.hub-help-btn, .hub-help { display: none; }   /* .hub-bell (нижче у файлі) інакше показав би кнопку будь-де */
@media (max-width: 768px) {
    .hub-topbar .hub-bell.hub-help-btn { display: inline-flex; }
    .hub-help {
        display: flex; flex-direction: column; position: fixed; inset: 0; z-index: 230;
        padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); box-sizing: border-box;
        background: var(--surface); visibility: hidden; transform: translateY(-100%);
        transition: transform var(--motion) var(--motion-ease), visibility 0s linear var(--motion);
    }
    .hub-help.open { visibility: visible; transform: none; transition: transform var(--motion) var(--motion-ease), visibility 0s; }
    .hub-help-head { display: flex; align-items: center; justify-content: space-between; min-height: 52px; padding: 0 16px; box-sizing: border-box; border-bottom: 1px solid var(--border); }
    .hub-help-head h2 { margin: 0; font-size: 16px; font-weight: 700; color: var(--text-primary); }
    .hub-help-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 6px 18px 24px; }
    .hub-help-body h3 { margin: 18px 0 8px; font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); }
    .hub-help-body dl { margin: 0; }
    .hub-help-body dt { font-size: 15px; font-weight: 700; color: var(--text-primary); }
    .hub-help-body dd { margin: 2px 0 12px; font-size: 14px; line-height: 1.45; color: var(--text-secondary); }
    /* Наприкінці опису — інші вкладки модуля («Про модуль · Налаштування»): на телефоні вкладок дошки немає (DESIGN §9) */
    .hub-help-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border); }
    .hub-help-links a {
        display: inline-flex; align-items: center; height: 38px; padding: 0 16px; border-radius: var(--radius-pill);
        border: 1px solid var(--border-strong); color: var(--text-primary); font-size: 14px; font-weight: 700; text-decoration: none;
    }
}

/* ── Шторки телефона «Модулі» і «Ще» — одне меню з капсулою (Fiobs 2026-10-13) ──────────────
   Обгортка .hub-drawer-clip — над капсулою, до половини екрана, і заходить на 22 px під неї (капсула вище):
   низ шторки заповнює заокруглені кути капсули — шва немає. Шторка виїжджає з-під краю капсули (translateY),
   обгортка обрізає все, що нижче. Пункти — плитками, щоб «Ще» вміщалося в половину екрана. */
.hub-drawer-overlay {
    position: fixed; inset: 0; z-index: 199;
    background: rgba(0,0,0,0.5);
    opacity: 0; pointer-events: none;
    transition: opacity var(--motion) ease;
}
.hub-drawer-overlay.open { opacity: 1; pointer-events: auto; }
.hub-drawer-clip {
    position: fixed; z-index: 200; left: 0; right: 0;
    bottom: calc(var(--dock-space) - 22px); height: 50dvh;
    overflow: hidden; pointer-events: none;
}
.hub-drawer {
    position: absolute; left: 0; right: 0; bottom: 0; max-height: 100%; box-sizing: border-box;
    overflow-y: auto; overscroll-behavior: contain;
    --surface: var(--surface-raised);   /* той самий тон, що й капсула; свято перевизначає обидві */
    background: var(--surface);
    border: 1px solid var(--border-strong); border-width: 1px 0 0;
    border-radius: 22px 22px 0 0;
    /* низ — під капсулою (22 px) і кулькою над нею */
    padding: 14px 14px calc(22px + var(--dock-rise) + 4px);
    font-family: var(--font-sans);
    /* +2 px: при дробовій висоті шторки її верхня рамка інакше визирає з обгортки тонкою смужкою */
    transform: translateY(calc(100% + 2px));
    transition: transform var(--motion) var(--motion-ease);
}
.hub-drawer.open { transform: none; pointer-events: auto; }
/* Шторка відкрита — у капсули немає верхньої рамки: шторка й капсула — одна поверхня */
body.hub-drawer-joined .hub-bottom-nav { border-top-color: transparent; border-top-left-radius: 0; border-top-right-radius: 0; }
@media (prefers-reduced-motion: reduce) { .hub-drawer, .hub-drawer-overlay { transition: none; } }
/* Повне меню — панель, потягнута вгору (navbar.html): панель піднімається на --hub-menu-h, а під нею — «Ще» з «Моїми модулями»
   (.is-full): обгортка від самого низу екрана, шторка без рамки й кутів — її верх ховається під панеллю, кути панелі не міняються */
.hub-drawer-full { display: none; }
.hub-drawer.is-full .hub-drawer-full { display: block; }
.hub-drawer-full .hub-drawer-grid { margin-bottom: 16px; }
body .hub-drawer-clip.is-full, body:has(.hub-ext:not(.is-off)) .hub-drawer-clip.is-full { bottom: 0; height: var(--hub-menu-h, 50dvh); }
.hub-drawer.is-full { border: 0; border-radius: 0; padding: 12px 14px calc(14px + env(safe-area-inset-bottom)); }
/* схована — рівно під панеллю (без «+2 px»: рамки згори немає, а зазор давав темну смужку між панеллю й меню на закритті) */
.hub-drawer.is-full:not(.open) { transform: translateY(100%); }
body.hub-menu-up :is(.hub-bottom-nav, .hub-ext) { transform: translateY(calc(-1 * var(--hub-menu-h, 0px))); }
/* Ручка «тягни» (Fiobs 2026-10-18: «міні покажчик того, що layout на телефоні можна витягнути угору»): коротка смужка по центру
   верху тієї частини, що зараз зверху, — відкритої шторки, рядка кнопок сторінки або самої панелі (у повному меню — на піднятій
   панелі: тягни вниз). Лише показ, жест — navbar.html */
@media (max-width: 768px) {
    :is(.hub-bottom-nav, .hub-ext, .hub-drawer)::after {
        content: ''; position: absolute; top: 5px; left: 50%; width: 32px; height: 4px; margin-left: -16px; border-radius: 2px;
        background: var(--text-muted); opacity: 0.45; pointer-events: none; transition: opacity var(--motion-fast) ease;
    }
    body.hub-drawer-joined :is(.hub-bottom-nav, .hub-ext)::after, body:has(.hub-ext:not(.is-off)) .hub-bottom-nav::after,
    .hub-drawer:is(:not(.open), .is-full)::after { opacity: 0; }
}
.hub-drawer-title {
    margin: 0 4px 10px;
    font-size: var(--text-label); font-weight: 700; letter-spacing: 0.1em;
    color: var(--text-muted); text-transform: uppercase;
}
.hub-drawer-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.hub-drawer-tile {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
    min-height: 72px; padding: 10px 4px; box-sizing: border-box;
    border-radius: 14px; border: none; background: none; cursor: pointer;
    color: var(--text-primary); text-decoration: none; text-align: center;
    font-family: var(--font-sans); font-size: 0.72rem; font-weight: 600; line-height: 1.2;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--motion-fast) ease, transform var(--motion-fast) ease;
}
.hub-drawer-tile:active { background: var(--surface-hover); transform: scale(0.96); }
.hub-drawer-tile > svg { width: 22px; height: 22px; color: var(--text-muted); }
.hub-drawer-tile .hub-sidebar-mod-icon { width: 34px; height: 34px; border-radius: 10px; }
.hub-drawer-tile .hub-sidebar-mod-icon svg { width: 18px; height: 18px; }
.hub-drawer-tile.is-add .hub-sidebar-mod-icon { background: var(--accent-dim); color: var(--accent); }
.hub-drawer-tile.is-add { color: var(--accent); }
/* Довге натискання на плитку чи пункт панелі — не меню посилання, не виділення тексту й не системне перетягування (iPhone):
   палець на панелі веде кульку */
.hub-drawer-tile, .hub-bottom-item { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; }
/* Поки відкрита шторка, текст сторінки під нею не виділяється */
body.hub-drawer-on { -webkit-user-select: none; user-select: none; }
/* Своя панель (налаштовується в каталозі модулів, modules.js): сторінки, на якій стоїш, на панелі немає (її пункт і «Модулі»
   зійшли з панелі) — кульки немає */
.hub-bottom-nav[data-pos="-1"] .hub-dock-bead { opacity: 0; }
/* Mobile-only chrome — never render on desktop (belt-and-suspenders so the
   bottom-sheets can't peek under any circumstance on wide screens). */
@media (min-width: 769px) {
    .hub-drawer, .hub-drawer-overlay { display: none !important; }
}


/* ── Notifications: bell + badge ───────────────────────── */
.hub-sidebar-head { display: flex; align-items: center; gap: 2px; padding-right: var(--space-3); }
.hub-sidebar-head .hub-sidebar-logo { margin-right: auto; }
.hub-bell {
    position: relative; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: var(--radius-sm);
    background: none; border: 1px solid transparent;
    color: var(--text-muted); cursor: pointer;
    transition: color var(--transition), background-color var(--transition);
}
/* Наведення — лише там, де є миша: на телефоні Safari лишав кнопку теми «натиснутою» після дотику (Fiobs 2026-10-14) */
@media (hover: hover) { .hub-bell:hover { color: var(--text-primary); background: var(--surface-hover); } }
.hub-bell:active { background: var(--surface-hover); }   /* відгук на дотик — лише поки палець на кнопці */
.hub-bell-badge {
    position: absolute; top: 3px; right: 3px;
    min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
    border-radius: var(--radius-pill); background: #EF4444; color: #fff;
    font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
    display: none;
}
.hub-bell-badge.show { display: block; animation: hub-bell-blink 1.2s ease-in-out infinite; }
@keyframes hub-bell-blink {
    0%, 100% { opacity: 1; transform: scale(1); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
    50%      { opacity: 0.55; transform: scale(0.9); box-shadow: 0 0 0 4px rgba(239, 68, 68, 0); }
}

/* ── Mobile top-bar (≤768px) ───────────────────────────── */
.hub-topbar { display: none; }
.hub-topbar-brand { font-size: 1.35rem; font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); text-decoration: none; margin-right: auto; }
.hub-topbar-brand span { color: var(--accent); }
@media (max-width: 768px) {
    .hub-topbar {
        display: flex; align-items: center; gap: 2px;
        position: sticky; top: 0; z-index: 90;
        height: 52px; padding: 0 var(--space-4);
        /* фоном сторінки, без рамки (2026-10-14, Fiobs: «прибрати перехід і різницю в кольорі… аби воно усе виглядало
           наче одне»): шапка — частина сторінки, а не окрема смуга */
        background: var(--bg);
    }
}

/* ── Notification panel ────────────────────────────────── */
.notif-overlay { position: fixed; inset: 0; z-index: 110; display: none; }
.notif-overlay.open { display: block; }
.notif-panel {
    position: fixed; z-index: 120;
    top: 56px; left: 232px; width: 360px; max-width: calc(100vw - 24px);
    max-height: 70vh; display: flex; flex-direction: column;
    /* з'являється плавно (спринт 2026-10-13: «зараз усе надто різке») — лише opacity/transform */
    opacity: 0; visibility: hidden; transform: translateY(-6px) scale(0.98); transform-origin: top left;
    transition: opacity var(--motion-fast) ease, transform var(--motion) var(--motion-ease), visibility 0s linear var(--motion);
    background: var(--surface); border: 1px solid var(--border-strong);
    border-radius: var(--radius); box-shadow: 0 12px 32px rgba(0,0,0,0.45);
    overflow: hidden;
}
.notif-panel.open { opacity: 1; visibility: visible; transform: none; transition: opacity var(--motion-fast) ease, transform var(--motion) var(--motion-ease), visibility 0s; }
@media (prefers-reduced-motion: reduce) { .notif-panel { transition: none; } }
/* Телефон: сповіщення — на весь екран, виїжджають згори (Fiobs 2026-10-14: «як «Ще», аби випадало зверху, або краще
   прям на увесь екран»); закриваються кнопкою «Закрити» в шапці — дзвіночок тоді під панеллю */
.notif-close { display: none; }
@media (max-width: 768px) {
    .notif-panel {
        inset: 0; width: auto; max-width: none; max-height: none; z-index: 230;
        border: 0; border-radius: 0; box-shadow: none; padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom);
        opacity: 1; transform: translateY(-100%);
        transition: transform var(--motion) var(--motion-ease), visibility 0s linear var(--motion);
    }
    .notif-panel.open { transform: none; transition: transform var(--motion) var(--motion-ease), visibility 0s; }
    .notif-panel .notif-head { min-height: 52px; box-sizing: border-box; }
    .notif-panel .notif-list { flex: 1; }
    .notif-close { display: inline; order: 9; }
}
.notif-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
.notif-title { font-weight: 700; font-size: var(--text-body); color: var(--text-primary); }
.notif-actions { display: flex; gap: var(--space-4); flex-shrink: 0; }
.notif-action { background: none; border: none; font-size: var(--text-caption); font-weight: 600; cursor: pointer; font-family: var(--font-sans); padding: 0; color: var(--accent); }
.notif-action:hover { color: var(--accent-hover); }
.notif-action.muted { color: var(--text-muted); }
.notif-action.muted:hover { color: var(--text-secondary); }
.notif-list { overflow-y: auto; }
.notif-item { position: relative; display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); cursor: pointer; transition: background-color var(--transition); }
@media (hover: hover) { .notif-item:hover { background: var(--surface-hover); } }
.notif-item.unread { background: var(--surface-hover); }
.notif-icon { background: color-mix(in srgb, var(--mod-color) 10.2%, transparent); color: var(--mod-color); flex-shrink: 0; width: 32px; height: 32px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; }
.notif-body-wrap { flex: 1; min-width: 0; padding-right: 14px; }
.notif-udot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); margin-right: 6px; vertical-align: middle; }
.notif-item-title { font-size: var(--text-body); font-weight: 600; color: var(--text-primary); }
.notif-item-text { font-size: var(--text-caption); color: var(--text-secondary); margin-top: 2px; }
.notif-item-time { font-size: 10px; color: var(--text-muted); margin-top: 4px; }
.notif-dismiss { position: absolute; top: 8px; right: 8px; width: 20px; height: 20px; border: none; background: none; color: var(--text-muted); font-size: 16px; line-height: 1; cursor: pointer; border-radius: var(--radius-sm); opacity: 0; transition: opacity var(--transition), color var(--transition); }
.notif-item:hover .notif-dismiss { opacity: 1; }   /* на дотик «×» з'являється після торкання рядка — лишаємо як є */
@media (hover: hover) { .notif-dismiss:hover { color: var(--text-primary); background: var(--surface-raised); } }
.notif-empty { padding: var(--space-6) var(--space-4); text-align: center; color: var(--text-muted); font-size: var(--text-body); }
.notif-gear { display: flex; align-items: center; }
.notif-push-cta { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border); color: var(--accent); font-size: var(--text-caption); font-weight: 600; text-decoration: none; }
.notif-push-cta[hidden] { display: none; }
@media (hover: hover) { .notif-push-cta:hover { background: var(--surface-hover); color: var(--accent-hover); } }

/* ── Переходи між сторінками (спринт 2026-10-13: «зараз усе надто різке») ────────────────────────
   Cross-document View Transitions: рамка (бічна смужка, верхня панель, капсула) стоїть на місці, вміст
   сторінки згасає й проявляється з легким підйомом; кулька капсули доїжджає до пункту нової сторінки, а
   іконки пунктів опускаються й піднімаються на свої місця. Браузер без підтримки (Firefox, iOS < 18.2)
   просто відкриває сторінку, як раніше. З prefers-reduced-motion — без переходів. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }
.hub-sidebar { view-transition-name: hub-rail; }
.hub-topbar { view-transition-name: hub-topbar; }
.hub-bottom-nav { view-transition-name: hub-dock; }
.hub-dock-bead { view-transition-name: hub-dock-bead; }
/* Іконки — за місцем на панелі (на місцях 1 і 3 — те, що поставив сам): перший дочірній елемент панелі — кулька */
.hub-bottom-nav > .hub-bottom-item:nth-child(2) > svg { view-transition-name: hub-dock-ic-0; }
.hub-bottom-nav > .hub-bottom-item:nth-child(3) > svg { view-transition-name: hub-dock-ic-1; }
.hub-bottom-nav > .hub-bottom-item:nth-child(4) > svg { view-transition-name: hub-dock-ic-2; }
.hub-bottom-nav > .hub-bottom-item:nth-child(5) > svg { view-transition-name: hub-dock-ic-3; }
.hub-bottom-nav > .hub-bottom-item:nth-child(6) > svg { view-transition-name: hub-dock-ic-4; }
::view-transition-group(*) { animation-duration: var(--motion-slow); animation-timing-function: var(--motion-ease); }
/* Бічна смужка після переходу — одразу нова, без перехресного згасання: старий і новий знімки, накладаючись, лишали
   «силуети» назв і підсвітки (Fiobs 2026-10-13: «прибери анімацію плавного затухання у бокової панелі»).
   Розгортання й згортання меню — звичайні переходи CSS, їх це не чіпає. */
::view-transition-group(hub-rail), ::view-transition-new(hub-rail) { animation: none; }
/* Рамка — над вмістом і під час переходу (шари переходу йдуть у порядку документа, а меню в ньому — першим) */
::view-transition-group(hub-rail), ::view-transition-group(hub-topbar), ::view-transition-group(hub-dock) { z-index: 1; }
::view-transition-group(hub-dock-bead) { z-index: 2; }
::view-transition-group(hub-dock-ic-0), ::view-transition-group(hub-dock-ic-1), ::view-transition-group(hub-dock-ic-2),
::view-transition-group(hub-dock-ic-3), ::view-transition-group(hub-dock-ic-4) { z-index: 3; }
::view-transition-old(hub-rail) { display: none; }
/* Поки нова сторінка проявляється (html.vt-in, base.html) — смужка не розгортається під курсором: розгортання посеред переходу
   Chrome малював обрізаною смугою поруч зі смужкою (Fiobs 2026-10-15, Chrome на Windows) */
html.vt-in body.nav-side .hub-sidebar { pointer-events: none; }
html.vt-in body.nav-side .hub-sidebar::after, html.vt-in body.nav-side .hub-sidebar * { transition: none !important; }
::view-transition-old(root) { animation: hub-page-out 0.16s ease both; }
::view-transition-new(root) { animation: hub-page-in var(--motion) var(--motion-ease) both; }
@keyframes hub-page-out { to { opacity: 0; } }
@keyframes hub-page-in { from { opacity: 0; transform: translateY(8px); } }
