/* «Древо альбома» (tree*.js, docs/studio-features/16-album-tree.md).
   Свой файл: vault.css и так больше девяти тысяч строк. Тот же слой
   responsive, что у vault.css, — правила темы и телефона действуют как везде.
   Телефон 375 px: ни одного элемента шире экрана (min-width: 0, переносы
   длинных названий, никаких фиксированных ширин), «Древо по времени» —
   вертикальная лента в одну колонку без линий, карточка — окно по центру
   с полями (владелец 04.10: «центрировать»).
   Цвет — не единственный признак: родство ещё и точками и словами,
   «нет в магазине» — словом. Фокус виден; без анимаций при reduced-motion. */
@layer responsive {
.tree-page { min-width: 0; }
.tree-page *, .tree-card * { min-width: 0; }
.tree-hero .tree-head-cover { flex: 0 0 auto; background: var(--bg-elev) center / cover no-repeat; }
.tree-title, .tree-sub { overflow-wrap: anywhere; }
.tree-dim { color: var(--text-dim); font-size: 12px; }
.tree-statusline { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 4px 0 10px; }
.tree-status { margin: 0; color: var(--text-mid, var(--text)); font-size: 14px; overflow-wrap: anywhere; }
.tree-status:empty { display: none; }
.tree-clock { font-size: 13px; font-variant-numeric: tabular-nums; }
.tree-clock:empty { display: none; }

/* Люди: кнопки-чипы с цветной точкой, «↗» — страница человека. */
.tree-people { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 12px; }
.tree-person { display: inline-flex; align-items: stretch; max-width: 100%; }
.tree-chip {
    display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; min-height: 36px;
    padding: 4px 10px; border: 1px solid var(--border); border-radius: var(--radius-pill);
    background: var(--bg-card); color: var(--text); font: inherit; font-size: 13px; cursor: pointer;
    text-align: left; overflow-wrap: anywhere;
}
.tree-chip:hover { border-color: var(--border-strong); }
.tree-chip.on { border-color: var(--accent); background: var(--accent-soft); }
.tree-chip-page {
    min-width: 36px; min-height: 36px; margin-left: 2px; border: 1px solid var(--border);
    border-radius: var(--radius-pill); background: transparent; color: var(--text-mid, var(--text)); cursor: pointer;
}
.tree-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
/* Точка человека с надёжной личностью — место под фото (person_face.js): 20px
   с самого начала (фото не сдвигает чипы), фото внутри — с кольцом его цвета
   (color = цвет человека), обложка — скруглённый квадрат. */
.tree-dot.pf-dot { position: relative; width: 20px; height: 20px; overflow: hidden; }
.tree-dot.pf-dot > img.pf-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.tree-dot.pf-dot.has-img { box-shadow: 0 0 0 2px currentColor; }
.tree-dot.pf-dot.is-album-cover { border-radius: 4px; }
.tree-pstat { color: var(--text-dim); font-family: var(--font-mono); font-size: 12px; }
.tree-link { background: none; border: 0; padding: 0; color: var(--accent-text); font: inherit; cursor: pointer;
    text-decoration: underline; text-underline-offset: 2px; }
.tree-unres { margin: 4px 0 10px; border: 1px solid var(--border); border-radius: var(--radius); padding: 6px 12px;
    background: var(--bg-card); }
.tree-unres > summary { cursor: pointer; min-height: 32px; display: flex; align-items: center; color: var(--text-mid, var(--text)); }
.tree-unres ul { margin: 6px 0; padding-left: 18px; }
.tree-unres-row { margin: 6px 0; overflow-wrap: anywhere; }
.tree-cands { margin: 2px 0 0; padding-left: 16px; font-size: 12px; }
.tree-ph { margin: 0 0 8px; }
.tree-more-people { margin: -6px 0 12px; }
.tree-more-people > summary { cursor: pointer; min-height: 34px; display: flex; align-items: center;
    color: var(--text-mid, var(--text)); font-size: 13px; }
.tree-more-people > summary::before { content: '▸'; margin-right: 6px; color: var(--text-dim); }
.tree-more-people[open] > summary::before { content: '▾'; }

/* Фильтры, вид, легенда, действия. */
.tree-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 4px 0 8px; }
.tree-filters { flex: 1 1 100%; }
.tree-filters > summary { cursor: pointer; min-height: 34px; display: flex; align-items: center; color: var(--text-mid, var(--text)); font-size: 13px; }
.tree-filters > summary::before, .tree-unres > summary::before { content: '▸'; margin-right: 6px; color: var(--text-dim); }
.tree-filters[open] > summary::before, .tree-unres[open] > summary::before { content: '▾'; }
.tree-filter-body { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 6px 0 8px; }
.tree-seg { display: inline-flex; flex-wrap: wrap; border: 1px solid var(--border); border-radius: var(--radius-pill);
    overflow: hidden; max-width: 100%; }
.tree-seg-btn { min-height: 34px; padding: 4px 12px; border: 0; background: transparent; color: var(--text-mid, var(--text));
    font: inherit; font-size: 13px; cursor: pointer; }
.tree-seg-btn.on { background: var(--accent-soft); color: var(--text-strong); }
.tree-years { display: inline-flex; flex-wrap: wrap; gap: 6px 10px; }
.tree-year-l { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-mid, var(--text)); }
.tree-year-l select { min-height: 32px; background: var(--bg-input); color: var(--text); border: 1px solid var(--border);
    border-radius: var(--radius-sm); }
.tree-check { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-size: 13px; cursor: pointer; }
.tree-check input { accent-color: var(--accent); }
.tree-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 10px; padding: 0; list-style: none;
    color: var(--text-dim); font-size: 12px; }
.tree-legend li { display: inline-flex; align-items: center; gap: 6px; }
.tree-lg { display: inline-block; width: 14px; height: 14px; border-radius: 4px; border: 1px solid var(--border-strong); }
.tree-lg-strong { border: 2px solid var(--accent); }
.tree-lg-oc { border-style: dashed; }
.tree-lg-no { opacity: 0.45; background: var(--bg-card-hover); }
.tree-lg-via { border-left: 3px solid var(--text-faint); }
.tree-kin { color: var(--accent-text); letter-spacing: 1px; font-size: 11px; }
.tree-actions { margin: 0 0 10px; }
.tree-panel { margin: 0 0 16px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius);
    background: var(--bg-card); overflow-wrap: anywhere; }
.tree-panel-title { margin: 0 0 8px; font-size: 15px; color: var(--text-strong); }
.tree-panel-msg { margin: 0 0 8px; }
.tree-panel-msg.err { color: var(--danger); }
.tree-pl { margin: 8px 0 0; padding-left: 0; list-style: none; }
.tree-pl-row { display: flex; align-items: flex-start; gap: 8px; padding: 6px 0; border-top: 1px solid var(--border-soft); }
.tree-pl-gap { display: inline-block; width: 34px; flex: 0 0 auto; }
.tree-pl-main { display: flex; flex-direction: column; gap: 2px; }
.tree-pl-why { color: var(--accent-text); font-size: 12px; }
.tree-share { display: flex; flex-wrap: wrap; gap: 8px; }
.tree-share-url { flex: 1 1 200px; min-height: 36px; padding: 6px 10px; background: var(--bg-input); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 12px; }
/* «Рассказ ИИ» — tree_story.css (карточка для чтения). */
.tree-empty p { overflow-wrap: anywhere; }
/* Кнопки пустого вида (tree_empty.js) — ряд по центру с зазором, перенос — тоже
   с зазором; на телефоне (360 px) «Показать» и «Сбросить фильтры» ложились
   столбиком встык и прилипали к тексту (ревью 08.10; как .album-missing .actions). */
.tree-empty-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
    align-items: center; margin-top: 12px; }

/* «Древо по времени»: секции, ряды по годам, плитки; линии — SVG поверх. */
.tree-time { position: relative; }
.tree-lines { position: absolute; top: 0; left: 0; pointer-events: none; overflow: visible; }
/* Линий много (каждый альбом — к корню): слабые — бледнее, сильные — ярче. */
.tree-line { fill: none; stroke: var(--border-strong); opacity: 0.35; }
.tree-line.strong { stroke: var(--accent-dim); opacity: 0.8; }
.tree-line.via { stroke-dasharray: 4 4; }
.tree-line.lit { opacity: 1; }
.tree-line.dim { opacity: 0.15; }
.tree-sec { position: relative; margin: 0 0 18px; }
.tree-sec-title { margin: 0 0 10px; font-size: 14px; color: var(--text-mid, var(--text)); font-weight: 600; }
.tree-sec-root { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.tree-root-wrap { display: flex; justify-content: center; width: 100%; }
.tree-row { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 10px; align-items: start; margin: 0 0 10px; width: 100%; }
.tree-year { padding-top: 10px; color: var(--text-dim); font-family: var(--font-mono); font-size: 12px; }
.tree-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); gap: 8px; }
.tree-tile {
    position: relative; display: flex; gap: 10px; align-items: flex-start; width: 100%; padding: 8px;
    border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card);
    color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.tree-tile:hover { border-color: var(--border-strong); background: var(--bg-card-hover); }
.tree-tile.strong { border: 2px solid var(--accent); }
.tree-tile.oc { border-style: dashed; }
.tree-tile.unavail { opacity: 0.5; }
.tree-tile.via { border-left: 3px solid var(--text-faint); }
.tree-tile.dim { opacity: 0.3; }
.tree-tile.lit { box-shadow: 0 0 0 2px var(--accent-strong); }
.tree-root-tile { max-width: min(100%, 340px); border: 2px solid var(--accent-strong); background: var(--accent-wash); }
/* Честная строка под корнем (root.cat_rest, 17.10): тёзки со страницы каталога — числом. */
.tree-cat-rest { position: relative; max-width: min(100%, 560px); margin: 0; padding: 4px 12px;
    border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-card);
    color: var(--text-mid, var(--text)); font-size: 12.5px; line-height: 1.5; text-align: center; overflow-wrap: anywhere; }
.tree-cover { width: 72px; height: 72px; flex: 0 0 72px; border-radius: var(--radius-sm); object-fit: cover; background: var(--bg-elev); }
.tree-cover-empty { display: flex; align-items: center; justify-content: center; color: var(--text-dim); font-size: 22px; }
.tree-tile-text { display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.tree-tile-title { font-weight: 600; color: var(--text-strong); font-size: 14px; }
.tree-tile-artist { color: var(--text-mid, var(--text)); font-size: 13px; }
.tree-tile-meta { color: var(--text-dim); font-size: 12px; }
.tree-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.tree-badge { padding: 1px 6px; border: 1px solid var(--border); border-radius: var(--radius-pill); font-size: 11px; color: var(--text-mid, var(--text)); }
.tree-badge-strong { border-color: var(--accent); color: var(--accent-text); }
.tree-badge-no { border-color: var(--danger); color: var(--text); }
.tree-badge-dl, .tree-badge-fav { color: var(--success); }

/* «Созвездие» — tree_islands.css (солнце и острова). */

/* Карточка альбома: окно по центру на любом экране. Места себе не задаёт —
   центровка и предел высоты общие (dialog:modal в style.css): своё
   «position/inset» уводило карточку в левый верхний угол (владелец 04.10).
   Длинный список людей листается внутри окна. */
.tree-card {
    border: 0; border-radius: var(--radius-lg); padding: 16px; width: 92vw; max-width: 520px;
    background: var(--bg-card); color: var(--text); box-shadow: var(--shadow-elev);
    overflow-y: auto;
}
.tree-card::backdrop { background: rgba(0, 0, 0, 0.6); }
/* Шапка с ✕ держится наверху окна, пока листается длинный список людей:
   на телефоне без Esc иначе ✕ уезжал на тысячи пикселей вверх, а затемнения
   для нажатия вокруг окна по центру — 8–15px (проверка 04.10). Во всю
   ширину и от самого верха (поля карточки перекрыты отрицательными полями,
   на месте шапка не сдвинулась) и с фоном карточки — строки уходят под неё,
   а не просвечивают сбоку. top: −16px — липкое место отсчитывается от края
   за полями прокручиваемого окна: при top: 0 над шапкой оставалась полоса
   16px, в которой просвечивал список. Как шапка «Сомелье» (vault.css). */
.tree-card-head {
    display: flex; gap: 12px; align-items: flex-start;
    position: sticky; top: -16px; z-index: 2;
    margin: -16px -16px 0; padding: 16px 16px 8px; background: var(--bg-card);
}
.tree-card-cover { width: 96px; height: 96px; flex: 0 0 96px; border-radius: var(--radius-sm); object-fit: cover; }
.tree-card-meta { flex: 1 1 auto; overflow-wrap: anywhere; }
.tree-card-meta h3 { margin: 0 0 4px; font-size: 17px; color: var(--text-strong); }
.tree-card-sub { color: var(--text-mid, var(--text)); }
/* «Обложка: Deezer ↗» — честный источник обложки (app/deezer_covers). */
.tree-card-src a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }
.tree-card-x { flex: 0 0 auto; min-width: 40px; min-height: 40px; }
.tree-card-sec { margin: 14px 0 6px; }
/* 8px снизу у шапки + 6px — прежний отступ 14px до списка. */
.tree-card-head + .tree-card-sec { margin-top: 6px; }
.tree-card-h { font-weight: 600; margin-bottom: 6px; }
.tree-card-people { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; }
.tree-card-person { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; overflow-wrap: anywhere; }
.tree-card-roles { color: var(--text-mid, var(--text)); font-size: 13px; }
.tree-src { font-size: 10px; }
.tree-card-note, .tree-card-avail, .tree-card-marks { margin: 8px 0; font-size: 13px; overflow-wrap: anywhere; }
.tree-card-avail.no { color: var(--warning); }
/* Оба сервиса (tree_card_both.js): «нигде не нашлось» — спокойно, приглушённым;
   каждый сервис строки — одним куском, перенос только между ними. */
.tree-card-avail.dim { color: var(--text-dim); }
.tree-card-seg { display: inline-block; max-width: 100%; }
.tree-card-actions { margin-top: 10px; }
/* «Открыть в Qobuz» / «Открыть в TIDAL» и остальные кнопки карточки — под
   палец на сенсорном экране (≥ 44 px), строка кнопок переносится. */
.tree-card-actions { display: flex; flex-wrap: wrap; gap: 8px; }
@media (pointer: coarse) {
    .tree-card-actions .btn { min-height: 44px; }
}
/* Входы функций в слоте шапки (tree_entries.js): свой контейнер не ломает ряд слота;
   кнопки — 44 px, как .ap-entry. */
.tree-ents { display: contents; }
.tree-head-extras .btn { min-height: 44px; }
.tree-head-extras .tree-ent-wait { visibility: hidden; }
/* Ряд управления и слот шапки сами ничего не рисуют. Пока сборка ищет людей, слот держит место
   невидимой копией кнопки; приход списка людей сдвигает ряд вниз, и сдвиг страницы (CLS) считал
   всю коробку ряда вместе с пустым местом копии (ревью 18.10, Chromium: 0,160 против 0,122 без
   входов на 375 px). Коробки без отрисовки — невидимы, их видимые части — видимы: сдвиг считают
   по тому, что видно; на экране ничего не меняется. */
.tree-controls, .tree-head-extras { visibility: hidden; }
.tree-controls > :not(.tree-head-extras), .tree-head-extras > :not(.tree-ents), .tree-ents > :not(.tree-ent-wait) { visibility: visible; }
.tree-card-why { margin: 6px 0 0; }

.tree-page button:focus-visible, .tree-card button:focus-visible, .tree-page select:focus-visible,
.tree-page input:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }

@media (max-width: 599px) {
    .tree-lines { display: none; }
    .tree-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
    .tree-year { padding-top: 0; }
    /* Лента: одна колонка, обложка слева — 30 альбомов листаются, а не
       превращаются в стену квадратов. */
    .tree-tiles { grid-template-columns: minmax(0, 1fr); gap: 6px; }
    .tree-tile { padding: 6px; gap: 8px; }
    .tree-cover { width: 56px; height: 56px; flex: 0 0 56px; }
    .tree-root-tile { max-width: 100%; }
    .tree-controls { gap: 8px; }
    .tree-card-cover { width: 72px; height: 72px; flex: 0 0 72px; }
    /* Оба сервиса: сервис на строку — высота строки не зависит от ответа. */
    .tree-card-seg { display: block; }
    .tree-card-sep { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .tree-tile, .tree-chip, .tree-line { transition: none; animation: none; }
}
} /* ── end @layer responsive ── */
