/* =========================================================
   📄 /styles_core/front/catalog/passport.css
   ТОПО / Каталог — правая карточка паспорта объекта

   Дизайн-проход по эскизу:
   - единая светлая «атласная» поверхность;
   - меньше ощущения вложенных карточек;
   - сильнее иерархия названия, типа и района;
   - факты, топонимика и карта читаются как части одного паспорта;
========================================================= */

/* =========================================================
   RIGHT COLUMN
========================================================= */

/*
 * Порядок колонок на экране: фильтры → список → паспорт. В разметке
 * паспорт записи стоит первым (поисковик читает сначала саму запись),
 * поэтому места колонкам задаёт order, а не порядок в HTML.
 */
.layout-sidebar > .layout-sidebar__side{ order:1; }
.layout-sidebar > .layout-sidebar__main{ order:2; }
.layout-sidebar > .catalog-object-side{ order:3; }

.catalog-object-side{
    min-width:0;
    margin-top:0;

    position:sticky;
    top:calc(var(--header-height, 86px) + var(--space-4, 16px));
    align-self:start;
}

/* =========================================================
   PASSPORT CARD
========================================================= */

.object-preview{
    /*
     * border-box обязателен: без него max-height ограничивает только
     * содержимое, а паддинги и рамки (около 30px) добавляются сверху —
     * карточка оказывается выше отведённого места, её низ уходит под
     * нижний край экрана, и чтобы дочитать статью, приходилось
     * прокручивать всю страницу до подвала вместо самого паспорта.
     */
    box-sizing:border-box;

    max-height:calc(100vh - var(--header-height, 86px) - var(--space-8, 32px));
    max-height:calc(100dvh - var(--header-height, 86px) - var(--space-8, 32px));
    overflow-y:auto;
    overscroll-behavior:contain;

    padding:calc(18px * var(--density)) calc(18px * var(--density)) calc(16px * var(--density));

    background:rgba(255,252,247,.86);
    border:1px solid rgba(92,67,38,.11);
    border-radius:14px;

    box-shadow:0 8px 24px rgba(61,41,3,.035);

    color:var(--color-fg);
}

/* =========================================================
   HEAD
========================================================= */

.object-preview__head{
    display:flex;
    flex-direction:column;
    /*
     * Заголовок и алтайское имя — один и тот же топоним на двух языках:
     * строки стоят вплотную (gap:0), а сама иерархия держится размером
     * шрифта (см. .object-preview__altai-name) — алтайское имя явно
     * мельче, читается как перевод-подпись под заголовком, а не как
     * второй равноценный заголовок. Строка «тип · район» — уже другая
     * категория данных, ей отдельный, заметно больший отступ (см.
     * margin-top у .object-preview__meta ниже).
     */
    gap:0;
    margin:0;
}

/*
 * flex-wrap задан явно: у .geo-result-title-row/.object-preview__title-row
 * в chips.css стоит flex-wrap:wrap, а здесь это свойство раньше не
 * перекрывалось никаким правилом — оно так и оставалось в силе. На
 * коротких топонимах-заголовках перенос не был заметен, но у длинных
 * заголовков свидетельств (source_article_passport) блок кнопок
 * целиком уезжал под заголовок отдельной строкой вместо того, чтобы
 * остаться справа в одну строку с ним.
 */
.object-preview__title-row{
    display:flex;
    flex-wrap:nowrap;
    align-items:flex-start;
    justify-content:space-between;
    gap:8px;
}


/*
 * Колонка «имя + алтайское написание» (в словарных паспортах — «слово
 * + читается») слева от кнопок. Раньше вторая строка стояла под всем
 * рядом, и зазор между ними задавала высота кнопок: у короткого имени
 * — щель, у имени в две строки — хвосты букв внахлёст. Блок, а не
 * flex: строки внутри — обычный поток, их flex-правила тут не нужны.
 */
.object-preview__names{
    flex:1 1 auto;
    min-width:0;
}

/* Одной строкой, а не переносом: длинное имя на узкой колонке
   уменьшается в размере (front/js/passport_name_fit.js ставит класс и
   подбирает font-size). Без JS — обычный перенос. */
.object-preview__names > .is-name-fit{
    white-space:nowrap;
}

.object-preview__title{
    display:flex;
    flex:1 1 auto;
    min-width:0;
    align-items:baseline;
    gap:7px;

    color:var(--color-fg);

    font-size:calc(1.52rem * var(--density));
    font-weight:900;
    line-height:1.06;
    letter-spacing:-.025em;
    /*
     * Длинное имя («Верхне-Каракокшинский») не уходит под кнопки
     * справа: anywhere, а не break-word — только он уменьшает
     * min-content у span внутри flex-заголовка, иначе слово целиком
     * держит ширину и вылезает за край. hyphens — перенос по слогам
     * там, где браузер знает русскую расстановку (lang="ru").
     */
    overflow-wrap:anywhere;
    hyphens:auto;
}

/*
 * На странице конкретной записи название в паспорте — H1 страницы (см.
 * page_hero/render.php). Глобальные стили h1 (typography.css: шрифт
 * заголовков и отступ снизу) здесь не нужны — вид тот же, что у div.
 */
h1.object-preview__title,
h1.dictionary-article-passport__name{
    margin:0;
    font-family:inherit;
}

/* Алтайское написание — из связанной словарной статьи. Единственная
   строка вариантов написания в паспорте объекта: тот же топоним, что
   и заголовок, поэтому шрифт — тот же самый (размер, начертание,
   межбуквенный интервал). Другие варианты (алиасы, OCR-варианты из
   словаря) намеренно не выводятся — паспорт объекта не дублирует
   данные словарной статьи, см. аналогичное решение для карточки
   списка каталога (toponym_card/render.php).

   Цвет — голубой геральдики Республики Алтай (флаг/герб: «голубой» —
   небо, горы, реки; точного HEX в открытых источниках не нашлось,
   #2E8FC1 — приближение). Локальный для этой строки, НЕ через
   --color-accent (тот зелёный — общий смысловой маркер сайта, здесь
   не подходит: эта строка про язык, а не про «есть ссылка/пояснение»). */
.object-preview__altai-name{
    display:flex;
    align-items:baseline;
    gap:7px;

    color:#2E8FC1;
    /*
     * Мельче заголовка (.object-preview__title — 1.52rem/900), но не
     * сильно — это и есть иерархия «главное имя / его алтайское
     * произношение», без слова «алт.» перед строкой. line-height:1 и
     * отрицательный margin-top: одного line-height:1 недостаточно —
     * у шрифта всё равно остаётся внутренний интерлиньяж над строчными
     * буквами, и на двусложных алтайских формах («Ада-Көл», «Ак-Айры»)
     * пара названий визуально «разваливалась» на два самостоятельных
     * заголовка вместо одного двуязычного.
     */
    font-size:calc(1.3rem * var(--density));
    font-weight:800;
    line-height:1;
    letter-spacing:-.02em;
    overflow-wrap:anywhere;
    hyphens:auto;
    /*
     * Раньше стояло -13px, потом -7px — оба внахлёст: хвосты «у», «р»,
     * «д» заголовка («Верх-Апшуяхта») ложились на заглавные алтайского
     * имени. -2px было вплотную; 2px оставляет
     * пару визуально одной группой (заголовок и алтайское имя ближе
     * друг к другу, чем к строке «тип · район» ниже — см. margin-top
     * у .object-preview__meta), но уже не внахлёст. НЕ на --density:
     * это компенсация внутреннего интерлиньяжа шрифта, а не обычный
     * межстрочный отступ, который должен сжиматься вместе с
     * плотностью (иначе на низких экранах пара расходится, а не
     * держится теснее).
     */
    margin-top:2px;
}

/* Имитация звуковой волны на время проигрывания произношения (см.
   preview.js, клик по .object-preview__listen) — рядом с алтайским
   словом, если оно показано (зелёная строка ниже заголовка), иначе
   рядом с самим заголовком (обычное чёрное название). currentColor
   подхватывает цвет своего слова — зелёный у .object-preview__altai-wave,
   цвет заголовка у .object-preview__title-wave — так волна всегда
   стоит у того слова, которое реально читается. */
.object-preview__altai-wave,
.object-preview__title-wave{
    display:inline-flex;
    align-items:center;
    gap:2px;
    height:14px;
}

.object-preview__altai-wave[hidden],
.object-preview__title-wave[hidden]{
    display:none;
}

.object-preview__altai-wave span,
.object-preview__title-wave span{
    width:3px;
    height:100%;
    border-radius:2px;
    background:currentColor;
    transform:scaleY(.3);
    animation:objectPreviewSoundWave .9s ease-in-out infinite;
}

.object-preview__altai-wave span:nth-child(2),
.object-preview__title-wave span:nth-child(2){
    animation-delay:.15s;
}

.object-preview__altai-wave span:nth-child(3),
.object-preview__title-wave span:nth-child(3){
    animation-delay:.3s;
}

@keyframes objectPreviewSoundWave{
    0%, 100%{ transform:scaleY(.3); }
    50%{ transform:scaleY(1); }
}

/* Все кнопки паспорта — одним узлом. Раньше «прослушать» стояла
   отдельно от группы сохранить/пожаловаться/поделиться/развернуть, и
   между ней и остальными в строке заголовка появлялся неровный
   зазор — .object-preview__title-row делит место между двумя своими
   flex-детьми поровну (justify-content:space-between), и то, что не
   было одним элементом, расползалось. Ряд полностью повторяет
   .dictionary-article-passport__tools. */
.object-preview__tools{
    display:flex;
    align-items:center;
    gap:6px;
    flex:0 0 auto;
}

/*
 * Высота — 34px, вровень с капсулой icon-actions (28px кнопка + 3px
 * паддинга с каждой стороны) и с .passport-expand-btn рядом — раньше
 * динамик был выше остальных кнопок ряда (38px) и разваливал строку.
 * Выделяется теперь не размером, а формой: скруглённый квадрат вместо
 * круга — тот же приём, что и у .passport-expand-btn ниже.
 */
.object-preview__listen{
    --topo-icon-size:20px;

    display:inline-flex;
    align-items:center;
    justify-content:center;
    flex-shrink:0;
    width:34px;
    height:34px;
    margin-right:5px;
    padding:0;

    border:1px solid rgba(122,92,46,.28);
    border-radius:10px;
    background:rgba(var(--color-primary-rgb),.09);
    color:#7a5c2e;
    font-size:1.05rem;
    line-height:1;
    cursor:pointer;
}

.object-preview__listen:hover{
    background:rgba(var(--color-primary-rgb),.17);
}

.object-preview__listen[hidden]{
    display:none;
}

/* =========================================================
   META — TYPE + DISTRICT
========================================================= */

.object-preview__meta{
    display:flex;
    align-items:center;
    flex-wrap:wrap;
    gap:5px;

    /*
     * Осознанный, а не случайный отступ: «тип · район» — другая
     * категория данных, не часть двуязычного заголовка над ним (см.
     * margin-top:-3px у .object-preview__altai-name, стягивающий пару
     * названий), поэтому ей нужен свой, явно больший зазор сверху —
     * заметно больше, чем расстояние внутри самой пары названий,
     * иначе граница между «блок имени» и «тип · район» не читается.
     * Фиксированное число, НЕ на --density — тот же случай, что и у
     * altai-name: это граница ритма между двумя смысловыми блоками, а
     * не «воздух», который должен сжиматься вместе с остальной
     * плотностью. При масштабировании на низких экранах (14px→8.7px)
     * рядом с уже полностью слитной парой названий разница читалась
     * как случайная дыра, а не как осознанная граница.
     *
     * Тонкая линия сверху — тот же приём и тот же цвет, что у границ
     * между разделами паспорта ниже (.object-toponymics border-top:
     * rgba(92,67,38,.10)): одной ширины отступа для границы «блок
     * имени / тип·район» оказалось недостаточно — рядом с паспортом,
     * где другие такие же границы прочерчены явной линией, эта читалась
     * как случайный зазор, а не как осознанная граница раздела.
     */
    margin-top:12px;
    padding-top:10px;
    border-top:1px solid rgba(92,67,38,.10);

    color:#9a6a2f;
    font-size:calc(.68rem * var(--density));
    font-weight:700;
    letter-spacing:.05em;
    text-transform:uppercase;
    line-height:1.25;
}

.object-preview__meta-type{
    display:inline-flex;
    align-items:center;
    gap:4px;
}

/*
 * Цветные плашки типа — как в утверждённом макете (сплошная заливка,
 * белый текст), не тонированная рамка. Цвет — та же группа, что уже
 * красит значок в панели фильтров (filters.css) и значки-связи на
 * карточке каталога (card.css: --settlement) — один и тот же смысл
 * одним и тем же цветом, просто в сплошном, а не тонированном виде.
 * У «Мест и территорий» своего цвета там нет — этот тип и остаётся
 * обычным текстом без плашки (см. .object-preview__meta-type без
 * модификатора выше).
 */
/*
 * line-height:1 — обязателен, не косметика. Плашка наследует
 * line-height:1.25 от .object-preview__meta (строка «тип · район»
 * выше): при padding всего в 1-2px эта унаследованная лишняя высота
 * строки давала на плашке рендер-баг — при разном масштабе страницы
 * браузер по-разному округлял дробные пиксели итоговой высоты, и
 * текст «плавал» на 1px то выше, то ниже центра плашки. С line-height:1
 * высота плашки жёстко привязана к метрике шрифта + padding, округление
 * стабильно на любом зуме.
 *
 * text-transform:none — сознательно перебивает uppercase, унаследованный
 * от .object-preview__meta. Прописные буквы («СЕЛО») оставляют под собой
 * пустое место, зарезервированное шрифтом под строчные хвостики (у, р, б),
 * которых у прописных нет — из-за этого при любом padding текст читался
 * визуально прилипшим к верху плашки, а точный симметричный отступ
 * пиксель в пиксель в браузере пользователя не подтверждался. Строчные
 * буквы («село») используют это место нормально, и плашка центрируется
 * честно через align-items:center у родителя, без подгона padding.
 */
.object-preview__meta-type--water,
.object-preview__meta-type--relief,
.object-preview__meta-type--settlements{
    padding:2px 6px;
    border-radius:4px;
    color:#fff;
    letter-spacing:.02em;
    line-height:1;
    text-transform:none;
}

.object-preview__meta-type--water{
    background:#287d90;
}

.object-preview__meta-type--relief{
    background:#52636d;
}

.object-preview__meta-type--settlements{
    background:#477b35;
}

.object-preview__meta-icon{
    color:var(--color-primary);
    font-size:.86rem;
    line-height:1;
    opacity:.85;
}

.object-preview__meta-dot{
    opacity:.6;
}

.object-preview__meta-district{
    font-weight:700;
}

/* =========================================================
   LEGACY BASE ROWS
========================================================= */

.object-preview__base{
    display:flex;
    flex-direction:column;
    gap:4px;
}

.object-preview__base-row{
    display:flex;
    align-items:baseline;
    gap:5px;

    color:var(--color-fg);
    font-size:14px;
    line-height:1.35;
}

.object-preview__base-label{
    color:var(--color-muted);
    font-weight:500;
}

.object-preview__base-value{
    color:var(--color-fg);
    font-weight:800;
}

.object-preview__body{
    color:var(--color-muted);
    font-size:14px;
    line-height:1.45;
}

.object-preview--empty{
    color:var(--color-muted);
}

/* =========================================================
   OFFICIAL GEOGRAPHIC REGISTRY
   Тихая подпись внизу паспорта.
========================================================= */

.object-preview-registry{
    margin-top:9px;
    padding-top:8px;

    color:var(--color-fg);
}

.object-preview-registry__entry + .object-preview-registry__entry{
    margin-top:7px;
}

/* Запись реестра — в одну строку вместе со стрелкой: не влезает —
   сокращается серая часть (издатель, реестр, дата), полный текст в title. */
.object-preview-registry__entry{
    display:flex;
    align-items:baseline;
    flex-wrap:nowrap;
    gap:4px;
    white-space:nowrap;

    font-size:10px;
    line-height:1.3;
}

.object-preview-registry__entry strong{
    font-weight:900;
}

.object-preview-registry__cite{
    color:inherit;
    text-decoration:none;
    border-bottom:1px solid transparent;
}

.object-preview-registry__cite:hover{
    border-bottom-color:currentColor;
}

.object-preview-registry__muted{
    min-width:0;
    overflow:hidden;
    text-overflow:ellipsis;
    color:#8a7b6c;
    font-size:9.25px;
}

.object-preview-registry__source-link{
    flex:0 0 auto;
    display:inline-block;
    margin-left:2px;
    color:#956427;
    font-weight:900;
    text-decoration:none;
    transition:color .15s ease, transform .15s ease;
}

/* Стрелочная ссылка — клик показывает цветом и сдвигом самой стрелки,
   без подчёркивания (см. .object-toponymics__more). */
.object-preview-registry__source-link:hover{
    color:var(--color-primary);
    transform:translate(1px, -1px);
}

/* =========================================================
   ADAPTIVE
========================================================= */

@media (max-width:1100px){
    .catalog-object-side{
        grid-column:1;
        grid-row:auto;
        position:static;
        margin-top:0;
    }
}

@media (max-width:700px){
    .object-preview{
        padding:16px;
    }

    .object-preview__title{
        font-size:1.35rem;
    }

    .object-preview__altai-name{
        font-size:1.02rem;
    }
}

/* =========================================================
   PASSPORT UPDATE ANIMATION
========================================================= */

[data-object-preview].is-changing [data-object-preview-name],
[data-object-preview].is-changing [data-object-preview-type],
[data-object-preview].is-changing [data-object-preview-district],
[data-object-preview].is-changing [data-object-preview-variants],
[data-object-preview].is-changing [data-object-preview-facts],
[data-object-preview].is-changing [data-object-preview-registry] {
    opacity:0.35;
    transform:translateY(4px);
}

[data-object-preview] [data-object-preview-name],
[data-object-preview] [data-object-preview-type],
[data-object-preview] [data-object-preview-district],
[data-object-preview] [data-object-preview-variants],
[data-object-preview] [data-object-preview-facts],
[data-object-preview] [data-object-preview-registry] {
    transition:
        opacity 220ms ease-out,
        transform 220ms ease-out;
}
