.p-promo{
    width:150px; aspect-ratio:192/352; border-radius:22px; position:relative; overflow:hidden; flex-shrink:0;
    display:flex; align-items:flex-end; padding:14px; color:#fff; background-size:cover; background-position:center;
  }
  .p-promo video, .p-promo img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:0; }

  /* profile edit button (shown only on the logged-in user's own profile) */
  .p-edit-btn{
    display:inline-flex; align-items:center; gap:7px; margin-bottom:14px; padding:9px 18px;
    border-radius:999px; border:1.5px solid var(--border); background:var(--surface); color:var(--ink);
    font-size:13px; font-weight:700; transition:all .15s ease;
  }
  .p-edit-btn:hover{ border-color:var(--ink); }
  .p-edit-btn svg{ width:14px; height:14px; }

  /* real video embeds (YouTube / Vimeo links) at proper 16:9 proportions */
  .video-embed{
    position:relative; width:100%; aspect-ratio:16/9; border-radius:12px; overflow:hidden; background:#000;
  }
  .video-embed iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
  .p-link-pill{
    display:flex; align-items:center; gap:8px; background:var(--surface); border:1px solid var(--border);
    border-radius:999px; padding:10px 16px; font-size:13px; font-weight:600; color:var(--ink); text-decoration:none;
    transition:border-color .15s ease;
  }
  .p-link-pill:hover{ border-color:var(--ink); }
  .p-link-pill .rkn-flag{ font-size:10.5px; color:#B4530A; }

  /* ---- Публикации в СМИ (ТЗ 22 сентября) — публичный профиль ----
     Список карточек-ссылок, а не пилюль (.p-link-pill выше) — тут два
     текстовых поля на запись (издание + название публикации), а не одна
     короткая подпись. */
  .p-publications-list{ display:flex; flex-direction:column; gap:10px; }
  .p-publication-item{
    display:flex; flex-direction:column; gap:2px; padding:12px 16px; border-radius:14px;
    border:1px solid var(--border); background:var(--surface); text-decoration:none; color:var(--ink);
    transition:border-color .15s ease;
  }
  .p-publication-item:hover{ border-color:var(--ink); }
  .p-publication-outlet{ font-size:12px; font-weight:600; color:var(--ink-faint); }
  .p-publication-title{ font-size:14px; font-weight:700; }

  .contacts-row{
    display:flex; flex-wrap:wrap; gap:12px; margin-bottom:30px;
  }
  /* Строка "контакты + Поделиться ссылкой" в шапке профиля (десктоп):
     кнопка "Поделиться ссылкой" (#p-share-wrap) стоит рядом с контактами
     (#p-contacts), а не отдельной строкой под ними, и прижата к правому
     краю. На мобиле (см. медиа-запрос ниже) возвращаем прежнее поведение —
     кнопка отдельной строкой под контактами, так компактнее на узком экране. */
  .contacts-share-row{
    display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap;
    margin-bottom:30px;
  }
  .contacts-share-row .contacts-row{ flex:1 1 auto; margin-bottom:0; }
  .contacts-share-row .share-link-row{ margin:0; flex-shrink:0; }
  @media(max-width:760px){
    .contacts-share-row{ flex-direction:column; align-items:stretch; }
    .contacts-share-row .contacts-row{ margin-bottom:16px; }
  }
  /* Обёртка вокруг каждого поля контакта (телефон/email/WhatsApp/Telegram) —
     нужна в JS (js/profile-page.js, renderContactField()), чтобы обновлять
     статус ОДНОГО поля независимо от остальных, не трогая соседние пилюли.
     display:contents убирает саму обёртку из flex-раскладки #p-contacts —
     детьми flex-контейнера по-прежнему выступают сами .contact-pill/button,
     как и раньше, до появления обёртки. */
  .contact-pill-wrap{ display:contents; }
  .contact-pill{
    display:flex; align-items:center; gap:8px; background:var(--surface); border:1px solid var(--border);
    border-radius:999px; padding:10px 16px; font-size:13px; font-weight:600;
  }
  .contact-pill .reveal{ color:var(--coral); font-weight:700; cursor:pointer; }
  .contact-pill.locked{ font: inherit; border:1px dashed var(--border); background:none; cursor:pointer; }
  .pro-upsell{ padding:6px 4px 2px; max-width:360px; }
  .pro-upsell h3{ font-size:19px; margin-bottom:10px; }
  .pro-upsell p{ font-size:13.5px; color:var(--ink-soft); margin-bottom:18px; line-height:1.5; }
  .cab-orient-row{ display:flex; align-items:center; flex-wrap:wrap; gap:14px; margin:8px 0 4px; font-size:12.5px; color:var(--ink-soft); }
  .cab-orient-row label{ display:flex; align-items:center; gap:5px; cursor:pointer; font-weight:600; }
  .cab-orient-label{ font-weight:700; color:var(--ink); }
  /* margin было "0 auto 12px" — верх 0, низ 12px. Внешний контейнер
     (.gallery-item/.project-card-media и т.п.) уже даёт свой собственный
     margin-bottom для отступа между карточками грида, так что этот нижний
     отступ был лишним и вдобавок асимметричным: серая "подложка" .gallery-item
     оставалась видна снизу вертикального видео, а сверху — нет (см. баг
     "Нет отступов сверху"). Раньше это уже приходилось отдельно обнулять
     для .project-card-media .media-vertical ниже — теперь тот же 0 просто
     задан здесь, в базовом правиле, и тот override больше не нужен как
     "заплатка", хотя он остаётся ради на всякий случай/явности. */
  .media-vertical{ aspect-ratio:9/16 !important; max-width:220px; margin:0 auto; object-fit:cover; }
  .media-vertical video, .media-vertical iframe{ width:100% !important; height:100% !important; object-fit:cover !important; }
  /* Explicit landscape frame so a clip tagged "horizontal" always displays that way,
     even if the source file's own dimensions are actually portrait. Mirrors .media-vertical. */
  .media-horizontal{ aspect-ratio:16/9 !important; object-fit:cover; overflow:hidden; }
  .media-horizontal video, .media-horizontal iframe{ width:100% !important; height:100% !important; object-fit:cover !important; }
  /* Base style for every "✕" remove button used across cabinet cards/thumbnails.
     Previously only top/right/width/height were set for gallery thumbnails with no
     position/background/shape rule to anchor to, so the button rendered as bare
     unstyled text sitting in normal document flow instead of a floating control. */
  .cab-item-remove{
    position:absolute; display:flex; align-items:center; justify-content:center; cursor:pointer;
    border-radius:50%; border:1.5px solid var(--border); background:rgba(255,255,255,0.94);
    color:var(--ink-soft); font-size:12px; line-height:1; z-index:3; transition:all .15s ease;
    box-shadow:0 1px 5px rgba(20,21,26,0.12);
  }
  .cab-item-remove:hover{ border-color:var(--coral); color:var(--coral); }

  .block{
    background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); padding:28px;
    margin-bottom:22px;
  }
  .block h3{ font-size:18px; margin-bottom:18px; display:flex; align-items:center; gap:10px; }
  .block h3 .num{ font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--ink-faint); font-weight:400; }

  .skills-wrap{ display:flex; flex-wrap:wrap; gap:10px; }
  .skill-tag{
    background:var(--bg); border:1px solid var(--border); padding:8px 14px; border-radius:999px; font-size:13px; font-weight:600;
  }
  .tag-clickable{ cursor:pointer; transition: all .15s ease; }
  .tag-clickable:hover{ background:var(--ink); color:#fff; border-color:var(--ink); }
  .tiny-tags-row{ display:flex; flex-wrap:wrap; align-items:center; gap:7px; margin-top:14px; margin-bottom:14px; }
  .tiny-tag{
    background:var(--bg); border:1px solid var(--border); padding:3px 9px; border-radius:999px;
    font-size:11px; font-weight:600; color:var(--ink-soft);
  }
  .tiny-tags-label{
    font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
    color:var(--ink-faint); margin-right:1px;
  }
  .tiny-tag-client{
    background:var(--coral-tint); border-color:var(--coral); color:var(--coral);
  }
  .tiny-tag-client.tag-clickable:hover{ background:var(--coral); color:#fff; border-color:var(--coral); }
  .tiny-clients-row{ margin-top:2px; }

  .timeline{ position:relative; padding-left:24px; }
  .timeline::before{ content:''; position:absolute; left:5px; top:6px; bottom:6px; width:2px; background:var(--border); }
  .t-item{ position:relative; padding-bottom:26px; }
  .t-item:last-child{ padding-bottom:0; }
  .t-item::before{
    content:''; position:absolute; left:-24px; top:4px; width:12px; height:12px; border-radius:50%;
    background:var(--coral); border:3px solid var(--coral-tint);
  }
  .t-year{ font-family:'JetBrains Mono',monospace; font-size:12px; color:var(--ink-faint); flex-shrink:0; width:44px; padding-top:4px; }
  .t-title{ font-weight:700; margin-top:0; }
  .t-desc{ font-size:13.5px; color:var(--ink-soft); margin-top:6px; line-height:1.6; max-width:600px; }

  .cases-grid{ display:grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap:18px; align-items:stretch; }
  .case-card-owner{
    display:flex; align-items:center; gap:8px; margin-bottom:12px; padding-bottom:12px; border-bottom:1px solid var(--border);
    font-size:12.5px; font-weight:700; color:var(--ink-soft); cursor:pointer;
  }
  .case-card-owner:hover{ color:var(--ink); }
  .case-card-owner .mini-avatar{
    width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    color:#fff; font-size:10px; font-weight:800; flex-shrink:0;
  }

  /* Case card — redesigned: minimal face (title / result / client), everything
     else (task, solution, tags, team) stays hidden until the existing
     openCaseModal() click reveals it. Pure restyle, no behaviour change. */
  .case-card{
    position:relative; border:1px solid var(--border); border-radius:var(--radius-md); padding:26px 28px;
    background:var(--surface); display:flex; flex-direction:column; height:100%; overflow:hidden;
    cursor:pointer; transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease, border-color .25s ease;
  }
  .case-card::before{
    content:''; position:absolute; top:0; left:0; width:4px; height:100%; background:var(--coral);
    transform:scaleY(0); transform-origin:top; transition:transform .3s cubic-bezier(.2,.8,.2,1);
  }
  .case-card:hover{ transform:translateY(-4px); box-shadow:var(--shadow-card); border-color:transparent; }
  .case-card:hover::before{ transform:scaleY(1); }
  .case-card-top{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
  .case-card-eyebrow{
    font-family:'JetBrains Mono',monospace; font-size:10.5px; font-weight:600; letter-spacing:.08em;
    text-transform:uppercase; color:var(--ink-faint);
  }
  .case-card-year{ font-family:'JetBrains Mono',monospace; font-size:11.5px; color:var(--ink-faint); }
  /* Баг «криво, если количество строк в заголовке разное»: заголовок и
     блок результата занимали ровно столько высоты, сколько нужно их
     реальному тексту (1-3 строки) — из-за этого RESULT-блок начинался на
     разной высоте у соседних карточек в одном ряду сетки (см. скриншот),
     хотя футер (View/лайк) внизу и так был прижат к низу карточки через
     margin-top:auto и потому не съезжал. Теперь заголовок ограничен
     максимум 3 строками (line-clamp — длиннее просто обрезается многоточием)
     и всегда резервирует высоту РОВНО под 3 строки (min-height в em, от
     собственного line-height — не зависит от того, что именно победит по
     каскаду font-size), поэтому позиция RESULT-блока (и всего, что ниже)
     теперь одинакова у всех карточек ряда независимо от длины заголовка. */
  .case-card-title{
    font-family:'Unbounded',sans-serif; font-size:18px; line-height:1.35; margin-bottom:16px; color:var(--ink);
    display:-webkit-box; -webkit-line-clamp:3; line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; min-height:4.05em;
  }
  .case-card-result{
    background:var(--bg); border-radius:var(--radius-sm); padding:14px 16px; margin-bottom:16px;
  }
  .case-card-result-label{
    display:block; font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
    color:var(--teal); margin-bottom:5px;
  }
  .case-card-result p{
    margin:0; font-size:13.5px; line-height:1.55; color:var(--ink-soft);
    display:-webkit-box; -webkit-line-clamp:3; line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
    /* тот же приём, что и у заголовка выше — резервируем высоту под 3
       строки, чтобы короткий результат не "поднимал" клиента/футер выше,
       чем у соседней карточки с трёхстрочным результатом. */
    min-height:4.65em;
  }
  .case-card-client{ display:flex; align-items:center; gap:8px; margin-bottom:6px; }
  .case-card-client-label{
    font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-faint);
  }
  .case-card-client-more{ font-size:11px; font-weight:700; color:var(--ink-faint); }
  .case-card-foot{
    margin-top:auto; padding-top:18px; display:flex; align-items:center; justify-content:space-between;
  }
  .case-card-cta{
    display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:700; color:var(--ink-soft);
    transition:color .2s ease;
  }
  .case-card:hover .case-card-cta{ color:var(--coral); }
  .case-card-cta-arrow{
    width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
    transition:transform .25s cubic-bezier(.2,.8,.2,1);
  }
  .case-card:hover .case-card-cta-arrow{ transform:translateX(3px); }

  /* Label-less variant of .case-card-result — same soft rounded box, used on
     cards that aren't a "Кейс" (projects, startups, opportunities), where a
     "Результат" label wouldn't make sense. */
  .case-card-desc-box{ background:var(--bg); border-radius:var(--radius-sm); padding:14px 16px; margin-bottom:16px; }
  .case-card-desc-box p{
    margin:0; font-size:13.5px; line-height:1.55; color:var(--ink-soft);
    display:-webkit-box; -webkit-line-clamp:3; line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
  }

  /* Compact team display for cards (catalog grids) — a row of small avatar +
     name chips, lighter than the .dm-team boxes used inside detail modals,
     which are too heavy to repeat once per card in a dense grid. */
  .team-chip-row{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:16px; }
  .team-chip{
    display:inline-flex; align-items:center; gap:6px; background:var(--bg); border:1px solid var(--border);
    border-radius:999px; padding:4px 12px 4px 4px; font-size:12px; font-weight:600; color:var(--ink-soft);
  }
  .team-chip.tag-clickable:hover{ border-color:var(--coral); background:var(--coral-tint); color:var(--ink); }
  .team-chip-avatar{
    width:20px; height:20px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    color:#fff; font-size:9px; font-weight:800; overflow:hidden; flex-shrink:0;
  }
  .team-chip-avatar img{ width:100%; height:100%; object-fit:cover; }

  /* Project card, redesigned to match the case-card look (js/projects-page.js
     uses projectCaseCardHtml()): same border/radius/hover as .case-card.
     Раньше обложка растягивалась на всю ширину карточки в натуральном
     соотношении сторон — на широких/высоких исходниках получалась гигантская
     картинка (жалоба "Гигантское изображение. Неудобно смотреть"). Теперь
     раскладка горизонтальная: обложка — 70% ширины карточки, фиксированное
     соотношение сторон + object-fit:cover, а текст/теги — оставшиеся 30%
     справа. На узких экранах снова складывается в колонку. */
  .project-case-card{ padding:0; overflow:hidden; flex-direction:row; align-items:stretch; }
  .project-case-card .project-case-card-media{ margin:0; width:70%; flex-shrink:0; display:flex; }
  /* Пропорции обложки больше не ломаются: раньше .project-card-media имела
     жёсткое aspect-ratio:16/10 + object-fit:cover, из-за чего любое
     изображение, не совпадающее с этим соотношением, обрезалось или
     "сплющивалось" (ТЗ Объект-1). Теперь для квадратных/горизонтальных
     обложек ширина колонки по-прежнему фиксирована (70%, как и раньше), а
     высота — авто, по реальным пропорциям кадра (object-fit:contain на
     случай видео/эмбедов с собственным соотношением). */
  .project-case-card .project-case-card-media .project-card-media{
    border-radius:0; width:100%; overflow:hidden; align-self:center;
  }
  .project-case-card .project-case-card-media .project-card-media img,
  .project-case-card .project-case-card-media .project-card-media video{
    width:100%; height:auto; max-height:520px; object-fit:contain;
  }
  .project-case-card .project-case-card-media .video-embed{ width:100%; height:auto; }
  .project-case-card .project-case-card-media .project-card-media.no-media,
  .project-case-card .project-case-card-media .project-card-media.link-media{ height:100%; align-self:stretch; }
  .project-case-card .case-card-body{ width:30%; padding:22px 24px; min-width:0; }
  /* Вертикальные обложки (ТЗ Объект-1): вместо фиксированной ширины
     колонки — фиксированная высота (ограничена видимой зоной экрана), а
     ширина уже подстраивается под пропорции кадра сама, без обрезки и
     деформации. Класс .cover-vertical проставляется в
     projectCoverOrientation()/projectCaseCardHtml() (card-render-helpers.js)
     по declared-ориентации обложки. */
  .project-case-card.cover-vertical .project-case-card-media{
    width:auto; max-width:42%; height:min(72vh, 560px); align-items:center; justify-content:center;
  }
  .project-case-card.cover-vertical .project-case-card-media .project-card-media{
    width:auto; height:100%; max-height:none;
  }
  .project-case-card.cover-vertical .project-case-card-media .project-card-media img,
  .project-case-card.cover-vertical .project-case-card-media .project-card-media video{
    width:auto; height:100%; max-height:none; object-fit:contain;
  }
  .project-case-card.cover-vertical .case-card-body{ width:auto; flex:1; }
  @media(max-width:760px){
    .project-case-card,
    .project-case-card.cover-vertical{ flex-direction:column; }
    .project-case-card .project-case-card-media,
    .project-case-card .case-card-body,
    .project-case-card.cover-vertical .project-case-card-media,
    .project-case-card.cover-vertical .case-card-body{ width:100%; max-width:none; }
    .project-case-card .project-case-card-media{ height:auto; }
    .project-case-card .project-case-card-media .project-card-media img,
    .project-case-card .project-case-card-media .project-card-media video{ max-height:70vh; }
    .project-case-card.cover-vertical .project-case-card-media{ height:auto; max-height:70vh; }
    .project-case-card.cover-vertical .project-case-card-media .project-card-media,
    .project-case-card.cover-vertical .project-case-card-media .project-card-media img,
    .project-case-card.cover-vertical .project-case-card-media .project-card-media video{ width:auto; height:auto; max-height:70vh; max-width:100%; }
    .project-case-card .case-card-body{ padding:20px 22px 22px; }
  }

  /* Legacy rules — still used by the profile page's own "Кейсы" block
     (js/profile-page.js), which renders its own markup and is out of scope
     for this restyle. */
  .case-card h4{ font-family:'Unbounded',sans-serif; font-size:15px; margin-bottom:10px; }
  .case-line{ font-size:13px; color:var(--ink-soft); margin-bottom:6px; }
  .case-line b{ color:var(--ink); }

  .masonry-grid{ columns:4 220px; column-gap:18px; }
  @media(max-width:1100px){ .masonry-grid{ columns:3 200px; } }
  @media(max-width:700px){ .masonry-grid{ columns:2 160px; } }

  /* Single-column list — used by the redesigned "Проекты" page: one card per
     row instead of the 4-column masonry, so every project reads like a case
     card rather than a small thumbnail packed into a dense grid.
     max-width matches #view-projects .listing-main (see catalog.css) — on
     that page the width is already capped by the aside column, but
     .stacked-grid is reused as-is on the profile page ("Проекты"/"Выставки")
     and in "Избранное"/"Победители", which have no aside, so without this
     cap the same card stretches edge-to-edge and its 70%-wide cover balloons
     to a huge height on wide screens. */
  .stacked-grid{ display:flex; flex-direction:column; gap:24px; max-width:760px; }

  /* Редизайн карточек "Выставки" в профиле (см. exhibitionProfileCardHtml()
     в js/card-render-helpers.js) — сознательно отличается от карточек
     проектов/кейсов: без обложки, компактная строка вместо крупной
     плашки с картинкой. Затрагивает только #p-exhibitions (блок
     "Выставки" на странице профиля) — .stacked-grid у "Проектов"/
     "Кейсов" и старые .case-card/.project-case-card карточки не
     трогаются. */
  #p-exhibitions.stacked-grid{ gap:10px; }
  .exh-list-card{
    display:flex; align-items:center; gap:18px;
    padding:18px 22px; background:var(--surface);
    border:1px solid var(--border); border-radius:var(--radius-sm);
    cursor:pointer; transition:border-color .15s ease, box-shadow .15s ease, transform .15s ease;
  }
  .exh-list-card:hover{ border-color:transparent; box-shadow:var(--shadow-card); transform:translateY(-2px); }
  .exh-list-year{
    font-family:'JetBrains Mono',monospace; font-size:14px; font-weight:600;
    color:var(--ink-faint); flex-shrink:0; min-width:44px;
  }
  .exh-list-body{ flex:1; min-width:0; }
  .exh-list-title{
    font-family:'Unbounded',sans-serif; font-size:15px; line-height:1.35;
    color:var(--ink); overflow-wrap:break-word;
  }
  .exh-list-venue{ font-size:13px; color:var(--ink-soft); margin-top:4px; }
  .exh-list-arrow{
    width:18px; height:18px; flex-shrink:0; color:var(--ink-faint);
    transition:transform .15s ease, color .15s ease;
  }
  .exh-list-card:hover .exh-list-arrow{ transform:translateX(3px); color:var(--coral); }
  @media(max-width:560px){
    .exh-list-card{ padding:14px 16px; gap:12px; }
    .exh-list-year{ font-size:12px; min-width:34px; }
  }

  /* Cofounder / opportunity cards now render as .case-card (see cofounder.js /
     opportunities.js) instead of the plainer .project-card — this just lines
     them up in even rows of equal-height cards, same as .cases-grid. */
  .startup-grid{ display:grid; grid-template-columns: repeat(auto-fill, minmax(280px,1fr)); gap:22px; align-items:stretch; }
  .opportunity-grid{ display:grid; grid-template-columns: repeat(auto-fill, minmax(280px,1fr)); gap:22px; align-items:stretch; }
  /* align-self:flex-start keeps this chip hugging its own text instead of
     stretching to the full card width — it sits as a bare child of
     .project-card-body (a flex column), which otherwise stretches every
     direct child to 100% width via the default align-items:stretch. */
  .opportunity-type-chip{ display:inline-block; align-self:flex-start; font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:600; letter-spacing:0.03em; padding:4px 10px; border-radius:999px; background:var(--blue-tint); color:var(--blue); margin-bottom:10px; }
  .opportunity-org-chip{ display:inline-flex; align-items:center; gap:4px; font-size:12px; font-weight:600; padding:4px 10px; border-radius:999px; background:var(--bg); color:var(--ink-soft); border:1px solid var(--border); }
  .opportunity-org-chip.link{ cursor:pointer; }
  .opportunity-org-chip.link:hover{ border-color:var(--ink); color:var(--ink); }
  /* Компания, привязанная к объявлению ("Возможности") или стартапу
     ("Кофаундер") — ТЗ 30.08, второй этап. Тот же принцип чипа, что и у
     .opportunity-org-chip (свободнотекстовое "Организация"), но с
     логотипом компании и общая для обоих разделов, поэтому вынесена в
     отдельный класс, а не переиспользует opportunity-* имя. */
  .company-chip{ display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:600; padding:4px 10px 4px 4px; border-radius:999px; background:var(--bg); color:var(--ink-soft); border:1px solid var(--border); text-decoration:none; }
  .company-chip:hover{ border-color:var(--ink); color:var(--ink); }
  .company-chip img{ width:20px; height:20px; border-radius:50%; object-fit:cover; flex-shrink:0; }
  .company-chip-fallback{ width:20px; height:20px; border-radius:50%; background:var(--violet-tint); color:var(--violet); font-size:10px; font-weight:700; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
  .project-card{
    break-inside:avoid; margin-bottom:18px; background:var(--surface); border:1px solid var(--border);
    border-radius:16px; overflow:hidden; display:block;
  }
  .project-card-media{ width:100%; display:flex; align-items:center; justify-content:center; background:var(--bg); overflow:hidden; color:#fff; }
  .project-card-media img, .project-card-media video{ width:100%; height:auto; display:block; }
  .project-card-media .video-embed{ aspect-ratio:16/9; width:100%; height:auto; border-radius:0; }
  .project-card-media .media-vertical{ max-width:none; width:100%; margin:0; }
  .project-card-media.no-media{ aspect-ratio:4/3; }
  .project-card-media.link-media{
    aspect-ratio:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px;
    background:var(--ink); color:#fff;
  }
  .project-card-media.link-media .gl-icon{ font-size:26px; }
  .project-card-body{ padding:14px 16px; }
  .project-card-owner{
    display:flex; align-items:center; gap:8px; margin-bottom:10px; cursor:pointer;
  }
  .project-card-owner:hover .project-card-owner-name{ text-decoration:underline; }
  .project-card-owner .mini-avatar{
    width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    color:#fff; font-size:10px; font-weight:800; flex-shrink:0; overflow:hidden;
  }
  .project-card-owner .mini-avatar img{ width:100%; height:100%; object-fit:cover; }
  .project-card-owner-name{ font-size:12px; font-weight:700; }
  .project-card-title{ font-weight:700; font-size:14px; margin-bottom:6px; }
  .project-card-desc{ font-size:12.5px; color:var(--ink-soft); line-height:1.5; margin-bottom:10px; }
  .project-card-year{ font-size:11px; color:var(--ink-faint); font-family:'JetBrains Mono',monospace; }
  .project-card-link{
    display:inline-flex; align-items:center; gap:5px; font-size:11.5px; font-weight:700; color:var(--coral); margin-top:8px;
  }
  .case-card h4{ font-family:'Unbounded',sans-serif; font-size:15px; margin-bottom:10px; }
  .case-line{ font-size:13px; color:var(--ink-soft); margin-bottom:6px; }
  .case-line b{ color:var(--ink); }

  .gallery-grid{ columns:4 200px; column-gap:20px; }
  @media(max-width:1100px){ .gallery-grid{ columns:3 180px; } }
  @media(max-width:640px){ .gallery-grid{ columns:2 140px; } }
  .gallery-item{
    display:block; width:100%; break-inside:avoid; margin-bottom:20px; border-radius:12px;
    overflow:hidden; background:var(--bg); position:relative;
  }
  .gallery-item img, .gallery-item video{ display:block; width:100%; height:auto; border-radius:12px; }
  .gallery-item video{ background:#000; }
  .gallery-play-badge{
    position:absolute; top:8px; right:8px; width:28px; height:28px; border-radius:50%;
    background:rgba(20,21,26,0.65); color:#fff; display:flex; align-items:center; justify-content:center; font-size:12px; pointer-events:none;
  }
  .gallery-item-meta{ padding:9px 11px 11px; }
  .gallery-item-caption{ font-size:12.5px; color:var(--ink-soft); line-height:1.45; }
  .gallery-item-author{ margin-top:6px; font-size:11px; color:var(--ink-faint); }
  .gallery-item-coauthors{ margin-top:6px; font-size:11px; color:var(--ink-faint); }
  .gallery-coauthor-link{ color:var(--coral); font-weight:700; cursor:pointer; }
  .gallery-coauthor-link:hover{ text-decoration:underline; }

  /* Кнопка "развернуть на весь экран" поверх каждого элемента медиагалереи —
     см. openGalleryLightbox() в js/likes-and-detail-modal.js. Сидит поверх
     видео/картинки/embed'а, не мешая их собственным элементам управления
     (play, громкость и т.п.), поэтому не растянута на всю карточку. */
  .gallery-item-expand{
    position:absolute; top:8px; left:8px; z-index:4; width:30px; height:30px; border-radius:50%;
    display:flex; align-items:center; justify-content:center; border:none; cursor:pointer;
    background:rgba(20,21,26,0.55); color:#fff; transition:background .15s ease, transform .15s ease;
  }
  .gallery-item-expand:hover{ background:rgba(20,21,26,0.8); transform:scale(1.06); }
  .gallery-item-expand svg{ width:14px; height:14px; }

  /* ---- Альбомы медиагалереи на публичном профиле ----
     Компактная строка-превью в духе доски Pinterest: слева название/кнопка,
     справа несколько небольших квадратных миниатюр (не больше 5 штук, без
     горизонтального скролла — умышленно НЕ показываем все файлы альбома
     тут, это просто анонс, полный список открывается по клику на "Посмотреть
     альбом"). Описание в свёрнутом виде намеренно не выводится (см.
     galleryAlbumsListHtml() в js/profile-page.js) — оно показывается только
     когда альбом открыт, см. .gallery-album-desc ниже и #p-gallery-active-header.
     Фон строки — светлый (не серый var(--bg)), просто белая карточка с
     тонкой обводкой, чтобы список альбомов не выглядел "подложкой". Отступы
     между строками и вокруг всего блока увеличены для большего воздуха. */
  /* Заголовок блока "Медиагалерея" — увеличенный отступ до списка альбомов
     (переопределяет общий .block h3{margin-bottom:18px} только для этого
     блока, остальные блоки профиля не затрагиваются). */
  #p-gallery-block h3{ margin-bottom:32px; }

  .gallery-albums-list{ margin-bottom:48px; display:flex; flex-direction:column; gap:30px; }
  .gallery-album-row{
    display:flex; gap:26px; align-items:center; flex-wrap:wrap;
    padding:24px 28px; border-radius:var(--radius-md); background:var(--surface);
    border:1px solid var(--border); transition:border-color .15s ease;
  }
  .gallery-album-row:hover{ border-color:var(--ink-faint); }
  /* Активный (открытый) альбом раньше выделялся сплошной насыщенной coral-
     обводкой — слишком контрастно на фоне остальных, спокойных строк.
     Смягчили до полупрозрачного оттенка того же акцента: заметно, но не
     "кричит". */
  .gallery-album-row.active{ border-color:rgba(255,77,109,0.38); }
  .gallery-album-row.active .gallery-album-title{ color:var(--coral); }
  .gallery-album-info{ flex:1 1 200px; min-width:160px; }
  .gallery-album-title{ font-family:'Unbounded',sans-serif; font-size:15px; margin-bottom:10px; }
  /* Больше отступа перед кнопкой, чтобы название/счётчик не "прилипали"
     к ней. */
  .gallery-album-meta{ font-size:11.5px; color:var(--ink-faint); margin-bottom:20px; }
  /* Описание — только в открытом альбоме (в превью-строке его нет вовсе).
     Крупнее и с ограниченной шириной строки, чтобы было удобно читать, а
     не "простыня" во всю ширину блока. Абзацы (несколько <p>, см.
     galleryAlbumDescHtml() в JS) получают собственный отступ друг от друга. */
  .gallery-album-desc{
    font-size:14.5px; color:var(--ink-soft); line-height:1.7; max-width:640px;
    margin-bottom:20px;
  }
  .gallery-album-desc p{ margin:0 0 12px; }
  .gallery-album-desc p:last-child{ margin-bottom:0; }
  /* Кнопка "Посмотреть альбом" — сплошная тёмная заливка (а не тонкий
     цветной контур, который на разных экранах читался как "кривая"
     рамка), чтобы кнопка выглядела как чёткое, аккуратное действие. */
  .gallery-album-view-btn{
    padding:10px 20px; font-size:12.5px; background:var(--ink); border-color:var(--ink); color:#fff;
  }
  .gallery-album-view-btn:hover{ background:var(--coral); border-color:var(--coral); color:#fff; }
  /* Ряд из нескольких маленьких квадратных превью — как в примере из
     Pinterest, а не растянутая на всю высоту полоса с прокруткой. Кроп по
     центру (object-fit:cover) — это не деформация (пропорции самого кадра не
     меняются, просто обрезаются края, как и в любой миниатюре галереи),
     углы скруглены. */
  .gallery-album-thumbs{
    flex:0 0 auto; display:flex; gap:12px; align-items:center;
  }
  .gallery-album-thumb-item{
    flex-shrink:0; width:56px; height:56px; border-radius:10px; overflow:hidden;
    display:flex; align-items:center; justify-content:center; background:var(--bg);
  }
  .gallery-album-thumb-item img, .gallery-album-thumb-item video{
    width:100%; height:100%; display:block; object-fit:cover;
  }
  .gallery-album-thumb-item.link-thumb, .gallery-album-thumb-item.audio-thumb{
    background:var(--ink); color:#fff; font-size:16px;
  }
  .gallery-album-thumb-item .video-embed{ width:100%; height:100%; }

  /* ===== Только для общей ленты раздела "Альбомы" (js/albums-page.js) =====
     Профиль автора альбома и его теги — их не показывает список альбомов на
     самой странице профиля (galleryAlbumsListHtml() в js/profile-page.js
     эти классы не выводит), поэтому ничего из блока ниже не задевает
     существующий вид "Медиагалереи" в профиле. */
  /* Раньше карточки шли впритык друг к другу (у #albums-page-list не было
     вообще никакого CSS-правила) — теперь между ними, как и в остальном
     приложении, зазор в 28px, плюс сама карточка чуть просторнее внутри. */
  .albums-feed-list{ display:flex; flex-direction:column; gap:28px; }
  .album-feed-row{ cursor:pointer; padding:28px 32px; }
  /* Кнопки лайка (сердечко со счётчиком) и избранного (закладка) — те же
     классы, что и на карточке профиля (см. cardHtml() в js/catalog.js), но
     в потоке ряда, а не поверх картинки, у альбома нет медиа-«шапки». */
  .gallery-album-actions{ display:flex; align-items:center; gap:10px; margin-top:16px; }
  .gallery-album-actions .card-like-btn, .gallery-album-actions .card-fav-btn{
    position:static; width:auto; height:auto; padding:8px 12px; border-radius:999px;
    background:var(--bg); border:1px solid var(--border); color:var(--ink-faint);
    display:inline-flex; align-items:center; gap:6px; font-size:12.5px;
  }
  .gallery-album-actions .card-like-btn svg, .gallery-album-actions .card-fav-btn svg{ width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.6; }
  .gallery-album-actions .card-like-btn.liked, .gallery-album-actions .card-fav-btn.active{
    background:var(--coral); border-color:var(--coral); color:#fff;
  }
  .gallery-album-actions .card-like-btn.liked svg, .gallery-album-actions .card-fav-btn.active svg{ fill:currentColor; }
  /* Мини-профиль автора — с отступом и сверху, и снизу, чтобы не "прилипать"
     ни к счётчику медиафайлов сверху, ни к кнопке "Посмотреть альбом" снизу
     (просили "достаточно воздуха, не вплотную"). */
  .gallery-album-author{
    display:flex; align-items:center; gap:10px; margin:14px 0 18px; cursor:pointer; width:max-content; max-width:100%;
  }
  .gallery-album-author-avatar{
    width:34px; height:34px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center;
    color:#fff; font-family:'Unbounded',sans-serif; font-weight:800; font-size:12px; overflow:hidden;
  }
  .gallery-album-author-avatar img{ width:100%; height:100%; object-fit:cover; }
  .gallery-album-author-info{ display:flex; flex-direction:column; gap:2px; min-width:0; }
  .gallery-album-author-name{ font-size:13px; font-weight:700; color:var(--ink); }
  .gallery-album-author-name:hover{ color:var(--coral); }
  .gallery-album-author-spec{ font-size:11.5px; color:var(--ink-faint); }
  /* Правая колонка карточки: превью медиа сверху, теги альбома под ними —
     здесь, и больше нигде в приложении, показываются пользовательские теги
     альбома. Сами чипы — это стандартный .tiny-tag.tag-clickable (см.
     tinyTagsHtml() в js/card-render-helpers.js), здесь только выравниваем
     обёртку .tiny-tags-row под правую колонку этой карточки. */
  .gallery-album-thumbs-col{ flex:0 0 auto; display:flex; flex-direction:column; align-items:flex-end; gap:12px; max-width:100%; }
  .gallery-album-thumbs-col .tiny-tags-row{ justify-content:flex-end; max-width:280px; margin:0; }
  @media(max-width:640px){
    .gallery-album-thumbs-col{ align-items:flex-start; width:100%; }
    .gallery-album-thumbs-col .tiny-tags-row{ justify-content:flex-start; max-width:100%; }
  }

  /* Заголовок открытого альбома над сеткой медиа (замещает список альбомов,
     пока альбом открыт): кнопка "← Все медиа" залита акцентным цветом, чтобы
     её было хорошо видно, затем — с увеличенным отступом — заголовок и
     полное описание. Отступ до самой сетки медиа тоже увеличен — чтобы
     текст описания и карточки медиа не "слипались". */
  .gallery-album-back-btn{
    display:inline-flex; align-items:center; gap:6px; background:var(--coral);
    border:1.5px solid var(--coral); border-radius:999px; padding:10px 20px; margin-bottom:32px;
    color:#fff; font-size:12.5px; font-weight:700; cursor:pointer; transition:all .15s ease;
  }
  .gallery-album-back-btn:hover{ background:var(--ink); border-color:var(--ink); }
  .gallery-album-active-title{ font-family:'Unbounded',sans-serif; font-size:18px; margin-bottom:14px; }
  /* Кнопка "Посмотреть альбом" сидит внутри карточки-строки альбома, у
     которой есть собственный внутренний отступ (padding-left:28px в
     .gallery-album-row) — поэтому у заголовка открытого альбома такой же
     левый отступ, иначе кнопка "← Все медиа"/заголовок/описание съезжают
     левее и не совпадают по краю с кнопкой в карточке выше. */
  #p-gallery-active-header{ margin-bottom:48px; padding-left:28px; }
  .gallery-empty-note{ font-size:13px; color:var(--ink-faint); padding:10px 0 4px; }

  @media(max-width:640px){
    .gallery-album-row{ flex-direction:column; align-items:stretch; }
    .gallery-album-thumbs{ flex-wrap:wrap; }
  }

  .t-item-row{ display:flex; gap:20px; align-items:flex-start; }
  .t-item-thumb{
    flex-shrink:0; max-width:280px; max-height:340px; border-radius:12px; background:var(--bg);
    border:1px solid var(--border); display:flex; align-items:center; justify-content:center; position:relative; overflow:hidden;
  }
  /* Media keeps whatever proportions it was uploaded with — width/height:auto plus
     object-fit:contain inside a generous max-width/max-height box means the browser
     never crops or stretches it, it just scales down to fit. Works the same for
     horizontal and vertical media, so no separate orientation classes are needed. */
  .t-item-thumb img, .t-item-thumb video{ max-width:278px; max-height:338px; width:auto; height:auto; object-fit:contain; display:block; }
  .t-item-thumb.link-thumb{ width:110px; height:110px; background:var(--ink); color:#fff; font-size:28px; }
  .t-item-thumb.media-broken{ width:110px; height:110px; }
  .t-item-thumb.media-broken video, .t-item-thumb.media-broken img, .t-item-thumb.media-broken .t-item-thumb-play{ display:none; }
  .t-item-thumb.media-broken::after{
    content:"⚠"; font-size:20px; color:var(--ink-faint);
  }
  .t-item-thumb-play{
    position:absolute; bottom:6px; right:6px; width:22px; height:22px; border-radius:50%; background:rgba(20,21,26,0.65);
    color:#fff; font-size:10px; display:flex; align-items:center; justify-content:center; pointer-events:none;
  }
  .t-item-body{ flex:1; min-width:0; }
  @media(max-width:640px){
    .t-item-row{ flex-direction:column; gap:12px; }
    .t-item-thumb{ max-width:100%; max-height:260px; width:100%; }
    .t-item-thumb img, .t-item-thumb video{ max-width:100%; max-height:258px; }
  }

  .review{ border-bottom:1px solid var(--border); padding:18px 0; }
  .review:last-child{ border-bottom:none; padding-bottom:0;}
  .review:first-child{ padding-top:0; }
  .review-head{ display:flex; align-items:center; justify-content:space-between; }
  .review-author{ font-weight:700; font-size:13.5px; }
  .review-stars{ display:flex; gap:2px; }
  .review-stars svg{ width:12px; height:12px; fill:var(--gold); }
  .review-text{ font-size:13.5px; color:var(--ink-soft); margin-top:8px; line-height:1.6; }
  .review-form{
    margin-top:22px; padding-top:22px; border-top:1px solid var(--border);
  }
  .review-form h4{ font-size:14px; margin-bottom:14px; }
  .review-form-row{ display:flex; gap:12px; align-items:center; margin-bottom:12px; flex-wrap:wrap; }
  .review-form-row input{
    flex:1; min-width:160px; padding:11px 14px; border-radius:12px; border:1.5px solid var(--border); font-size:13.5px;
    font-family:inherit; background:#FCFCFE;
  }
  .review-form-row input:focus{ outline:none; border-color:var(--ink); }
  .review-stars-input{ display:flex; gap:4px; }
  .review-stars-input .rs-star{ cursor:pointer; font-size:22px; color:var(--border); user-select:none; line-height:1; }
  .review-stars-input .rs-star.filled{ color:var(--gold); }
  .review-form textarea{
    width:100%; padding:12px 14px; border-radius:12px; border:1.5px solid var(--border); font-size:13.5px;
    font-family:inherit; background:#FCFCFE; resize:vertical; min-height:80px; margin-bottom:14px;
  }
  .review-form textarea:focus{ outline:none; border-color:var(--ink); }

  footer{ text-align:center; padding:30px; font-size:12px; color:var(--ink-faint); font-family:'JetBrains Mono',monospace; }

  #app-loading-screen{
    position:fixed; inset:0; z-index:9999; background:var(--bg);
    display:flex; align-items:center; justify-content:center;
  }
  .app-loading-spinner{
    width:34px; height:34px; border-radius:50%;
    border:3px solid var(--border); border-top-color:var(--ink);
    animation: app-loading-spin .7s linear infinite;
  }
  @keyframes app-loading-spin{ to{ transform:rotate(360deg); } }
  .tap-feedback-spinner{
    display:inline-block; width:15px; height:15px; border-radius:50%;
    border:2px solid currentColor; border-top-color:transparent; opacity:0.85;
    animation: app-loading-spin .7s linear infinite; vertical-align:middle;
  }
  .tap-feedback-dim{ opacity:0.55; pointer-events:none; transition:opacity .1s ease; }

/* ===== Кейсы на странице «Кейсы» – одна колонка ===== */
#view-cases .cases-grid {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Опционально: ограничиваем ширину карточек, чтобы они не растягивались */
#view-cases .cases-grid .case-card {
  max-width: 760px;
  width: 100%;
}

/* ===== Выравнивание кнопки "Смотреть" и лайка в карточках ===== */
.case-card-foot .project-card-link,
.case-card-foot .case-card-cta {
  margin-top: 0;
  line-height: 1;
  display: inline-flex;
  align-items: center;
}

.case-card-foot .like-btn {
  margin: 0;
}