:root{
    /* Где стоит цитата на первом экране — от нижнего края окна.
       Одно значение на двоих: им же задан пустой низ первого экрана. */
    --sub-bottom:clamp(110px,21vh,250px);
    --bg:#F6F8F4;
    --surface:#FFFFFF;
    --ink:#16211C;
    --muted:#5C6B62;
    --line:#DDE4DA;
    --accent:#1E6F52;
    --accent-soft:#E4EFE7;
    --on-accent:#FFFFFF;
    --shadow:0 1px 2px rgba(22,33,28,.06), 0 12px 32px rgba(22,33,28,.08);
    --veil:rgba(252,253,251,.78);
    --veil-top:rgba(252,253,251,.44);
    /* снимки должны отрываться от фона, а не лежать на нём плёнкой */
    --lift:0 16px 34px rgba(20,45,34,.18), 0 4px 10px rgba(20,45,34,.10);
    --lift-hi:0 24px 46px rgba(20,45,34,.24), 0 5px 12px rgba(20,45,34,.12);
    /* В ленте плитки стоят плотно, и широкие тени сливаются в тёмную полосу.
       Здесь тень короче — отрыв читается, грязи не возникает. */
    --lift-mq:0 8px 18px rgba(20,45,34,.20), 0 2px 5px rgba(20,45,34,.12);
    --lift-mq-hi:0 13px 26px rgba(20,45,34,.26), 0 3px 7px rgba(20,45,34,.14);
    --radius:5px;
    --step-0:1rem;
    --step-1:1.2rem;
    --step-2:1.55rem;
    --step-3:2.1rem;
    --step-4:3.1rem;
    --step-5:clamp(2.7rem, 6.2vw, 4.4rem);
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]){
      --bg:#0E1512;
      --surface:#16201B;
      --ink:#E7EEE8;
      --muted:#94A79B;
      --line:#25332B;
      --accent:#5CBE92;
      --accent-soft:#1B2C24;
      --on-accent:#0E1512;
      --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
      --veil:rgba(16,24,20,.82);
      --veil-top:rgba(16,24,20,.52);
      --lift:0 18px 38px rgba(0,0,0,.55), 0 4px 12px rgba(0,0,0,.42);
      --lift-hi:0 26px 50px rgba(0,0,0,.62), 0 6px 14px rgba(0,0,0,.48);
      --lift-mq:0 9px 20px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.4);
      --lift-mq-hi:0 14px 28px rgba(0,0,0,.58), 0 3px 8px rgba(0,0,0,.45);
    }
  }
  :root[data-theme="dark"]{
    --bg:#0E1512;
    --surface:#16201B;
    --ink:#E7EEE8;
    --muted:#94A79B;
    --line:#25332B;
    --accent:#5CBE92;
    --accent-soft:#1B2C24;
    --on-accent:#0E1512;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
    --veil:rgba(14,21,18,.86);
    --veil-top:rgba(14,21,18,.58);
  }

  *{box-sizing:border-box}
  /* Ленты идут во всю ширину окна (100vw), а 100vw считается вместе\r
     с полосой прокрутки — отсюда лишние пиксели вбок и съезжающая шапка.\r
     clip, а не hidden: hidden ломает липкую шапку. */
  html{overflow-x:clip}
  /* Место под вертикальную полосу прокрутки держим всегда: на коротких
     экранах (ввод кода) она пропадает, ширина окна прыгает — и шапка
     вместе с лентами уезжает вбок. */
  html{scrollbar-gutter:stable}
  body{
    margin:0;
    background:var(--bg);
    color:var(--ink);
    font-family:"Karla","Segoe UI",system-ui,sans-serif;
    font-size:var(--step-0);
    line-height:1.6;
    -webkit-font-smoothing:antialiased;
  }
  h1,h2,h3{font-family:"Fraunces",Georgia,"Times New Roman",serif;font-weight:400;text-wrap:balance;margin:0;line-height:1.1}
  /* Подчёркивание рисуем сами там, где оно нужно (адреса в разделе «Связаться»):
     родное съезжает под буквы с хвостами и спорит с рамкой. */
  a{color:inherit;text-decoration:none}
  footer.site a:hover{color:var(--accent)}
  button{font:inherit;color:inherit;cursor:pointer;border:0;background:none}

  .wrap{max-width:1080px;margin:0 auto;padding:0 28px}

  header.site{
    position:sticky;top:0;z-index:40;
    background:color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter:blur(10px);
    border-bottom:1px solid var(--line);
  }
  /* Шапка чуть выше обычного: в неё садится логотип, уехавший с первого
     экрана (150 px по ширине = 58 px по высоте), и ему нужен воздух. */
  /* Текстовое имя из шапки убрано: при прокрутке туда садится сам логотип,
     и два имени спорили друг с другом. Навигация прижата вправо. */
  .bar{display:flex;align-items:center;justify-content:flex-end;gap:24px;padding:8px 0;min-height:58px}
  .logo{font-family:"Fraunces",Georgia,serif;font-size:var(--step-1);letter-spacing:.01em;transition:opacity .3s ease}
  .logo em{font-style:italic;color:var(--accent)}
  /* Имя приехало в шапку картинкой — текстовая копия рядом лишняя. */
  body.logo-up .logo{opacity:0;pointer-events:none}
  /* Три варианта меню — выбрать один, лишние потом убрать. */
  nav.links{display:flex;align-items:center;color:var(--muted)}
  nav.links button{position:relative;transition:color .2s ease, background .2s ease, border-color .2s ease}
  nav.links button:hover,nav.links button:focus-visible{color:var(--accent)}

  /* Меню: прописные вразрядку, при наведении подчёркивание вырастает из
     центра. Выбрано Алёной 02.09.2026 из трёх вариантов, два других
     (курсивная антиква и капсулы) убраны вместе с переключателем. */
  nav.links{gap:30px;font-size:.74rem;letter-spacing:.2em;text-transform:uppercase}
  nav.links button::after{
    content:"";position:absolute;left:50%;right:50%;bottom:-7px;height:1px;
    background:var(--accent);transition:left .25s ease, right .25s ease;
  }
  nav.links button:hover::after,
  nav.links button:focus-visible::after{left:0;right:0}

  /* ---- имя на первом экране: готовый логотип, собранный Алёной ----
     Логотип ушёл из потока (position:fixed): он живёт на прокрутке и
     переезжает в шапку, поэтому первый экран держит высоту сам. */
  /* Подпись стоит в нижней трети первого экрана, а не вплотную к его краю:
     у самого низа она читалась как случайная строка, а на коротком экране
     ныряла под панель задач. Подвесить её прямо под логотипом нельзя —
     логотип не в потоке и уезжает вверх сам, они бы наложились.
     Нижний отступ и задаёт зазор между именем и цитатой: скрипт цитату
     не трогает, а имя при подъёме идёт со скоростью страницы — зазор
     сам собой остаётся постоянным. */
  .hero{
    min-height:calc(100svh - 58px);
    display:flex;flex-direction:column;align-items:center;justify-content:flex-end;
    padding:0 0 var(--sub-bottom);text-align:center;
  }
  .wordmark{aspect-ratio:1100/429}
:root{--logo-script:url(/assets/logo-leona.png);--logo-print:url(/assets/logo-alyona.png)}
  /* Логотип живёт на прокрутке (принято 30.08.2026): крупный по центру
     первого экрана, при прокрутке уменьшается до ~150 px и садится по
     центру шапки, возврат наверх разворачивает обратно. Всё считается от
     положения прокрутки, поэтому обратный ход достаётся даром — тот же
     путь читается в другую сторону. */
  .wordmark{
    position:fixed;left:50%;top:50%;z-index:58;
    width:min(52vw, 540px);aspect-ratio:1100/429;
    transform:translate3d(-50%,-50%,0);
    transform-origin:50% 50%;
    will-change:transform;
    pointer-events:none;
    border:0;background:none;padding:0;
    /* drop-shadow идёт по альфа-каналу, то есть по самим буквам,
       а не по прямоугольнику картинки. */
    filter:drop-shadow(0 2px 7px rgba(8,16,12,.5));will-change:transform;
    transition:filter .45s ease;
  }
  /* Уехал в шапку — тень гаснет: там своя подложка, тень под ней лишняя.
     Переключаем классом на пороге, а не пересчитываем filter в каждом кадре:
     фильтры дороги, их нельзя трогать по 60 раз в секунду. */
  .wordmark.up{
    filter:drop-shadow(0 3px 10px rgba(8,16,12,0)) drop-shadow(0 1px 2px rgba(8,16,12,0));
  }
  .wordmark.hit{pointer-events:auto;cursor:pointer}
  .wm{
    position:absolute;inset:0;width:100%;height:100%;
    background-repeat:no-repeat;background-position:center;background-size:contain;
  }
  .wm-script{background-image:var(--logo-script);z-index:1}
  /* Печатное имя белое: на светлой теме гасим фильтром, вместо второй копии
     картинки. Фильтр вынесен в переменную — во входной анимации filter
     задаётся целиком, и brightness иначе бы затёрся. */
  .wm-print{
    background-image:var(--logo-print);z-index:2;
    --print-fx:brightness(.14);filter:var(--print-fx);
  }
  @media (prefers-color-scheme: dark){
    :root:not([data-theme="light"]) .wm-print{--print-fx:none}
  }
  :root[data-theme="dark"] .wm-print{--print-fx:none}

  /* ---- вход с занавесом (тайминг утверждён Алёной 30.08.2026, не менять) ----
     Занавес не двигает логотип: имя лежит поверх шторок и остаётся на месте,
     уезжает только подложка. Поэтому не нужны перелёты из центра занавеса
     в позицию первого экрана. */
  .curtain{position:fixed;inset:0;z-index:56;transform:translateY(0)}
  .curtain.c1{background:#08211B}
  .curtain.c2{background:#10453A;z-index:55}
  body:not(.intro) .curtain{display:none}

  /* Каллиграфия прописывается свипом: маска вдвое шире элемента и едет
     справа налево. Анимируется mask-position — честное движение, в отличие
     от интерполяции самих градиентов. */
  .wm-script{
    -webkit-mask-image:linear-gradient(102deg,#000 0 34%,rgba(0,0,0,.55) 40%,transparent 47%);
            mask-image:linear-gradient(102deg,#000 0 34%,rgba(0,0,0,.55) 40%,transparent 47%);
    -webkit-mask-size:250% 100%;mask-size:250% 100%;
    -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    -webkit-mask-position:0% 0;mask-position:0% 0;
  }
  body.intro .wm-script{-webkit-mask-position:100% 0;mask-position:100% 0}
  body.intro-run .wm-script{animation:write 3.5s cubic-bezier(.62,.03,.35,1) 0s forwards}
  @keyframes write{
    from{-webkit-mask-position:100% 0;mask-position:100% 0}
    to  {-webkit-mask-position:0% 0;  mask-position:0% 0}
  }
  body.intro .wm-print{opacity:0}
  /* Пауза между «Leona» и появлением «ALYONA» укорочена 07.09.2026:
     задержка 2.95 с вместо 3.28. Сами длительности (письмо 3.5 с,
     проявление 1.8 с) утверждены Алёной 30.08 и не трогаются — режется
     только промежуток. Теперь имя целиком собрано к 4.75 с, ровно к тому
     моменту, когда трогается занавес, и оба слова видны до его подъёма. */
  body.intro-run .wm-print{animation:printin 1.8s cubic-bezier(.2,.7,.3,1) 2.95s forwards}
  @keyframes printin{
    from{opacity:0;transform:scale(1.05);filter:blur(7px) var(--print-fx)}
    to  {opacity:1;transform:none;filter:blur(0) var(--print-fx)}
  }
  /* Шторки трогаются раньше — 4.48 и 4.54 вместо 4.72 и 4.78 (07.09.2026):
     Алёна просила сократить паузу между появлением имени и подъёмом.
     Скорость подъёма (.55 с) и сдвиг между шторками (.06 с) не тронуты —
     они утверждены 30.08. Дальше сдвигать нельзя: имя проявляется
     до 4.75 с, и слишком ранний занавес читается как «имя ускорилось». */
  body.intro-run .curtain.c1{animation:lift .55s cubic-bezier(.72,0,.24,1) 4.48s forwards}
  body.intro-run .curtain.c2{animation:lift .55s cubic-bezier(.72,0,.24,1) 4.54s forwards}
  @keyframes lift{to{transform:translateY(-101%)}}
  body.intro .hero-sub{opacity:0}
        body.intro-run .hero-sub{
    opacity:1;
    -webkit-mask-image:linear-gradient(100deg,#000 0 30%,rgba(0,0,0,.5) 39%,transparent 47%);
            mask-image:linear-gradient(100deg,#000 0 30%,rgba(0,0,0,.5) 39%,transparent 47%);
    -webkit-mask-size:260% 100%;mask-size:260% 100%;
    -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    animation:writeSub 5.4s cubic-bezier(.46,.05,.45,1) 4.15s both;
  }
  @keyframes writeSub{
    from{-webkit-mask-position:100% 0;mask-position:100% 0}
    to  {-webkit-mask-position:0% 0;  mask-position:0% 0}
  }
  @keyframes subin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
  @media (prefers-reduced-motion: reduce){
    body.intro-run .wm-script,body.intro-run .wm-print,body.intro-run .hero-sub,
    body.intro-run .curtain.c1,body.intro-run .curtain.c2{animation-duration:.01s;animation-delay:0s}
  }

  /* Цитата под именем. Пока логотип в полный рост, её нет: она проявляется
     при прокрутке и остаётся стоять над лентой работ. Три варианта набора. */
  /* Цитата вынута из потока и прикреплена к окну (31.08.2026). Так её
     ведёт тот же скрипт и тот же кадр, что и логотип, — и они не могут
     разъехаться. Пока она ехала в потоке, её вёз браузер (мгновенно), а
     логотип — скрипт (кадром позже), и Алёна видела, как логотип «дрожит»
     относительно цитаты. Высоту первого экрана держит min-height у .hero,
     поэтому лента работ от этой перестановки не сдвинулась.
     z-index ниже шапки (40): уезжая вверх, цитата уходит ПОД неё. */
  .hero-sub{
    position:fixed;left:0;right:0;bottom:var(--sub-bottom);z-index:20;
    color:var(--muted);margin:0 auto;max-width:66ch;
    pointer-events:none;will-change:transform;
  }
  .hs-b{display:block}
  .hs-w{display:inline-block}

  /* Курсивная антиква — выбрана Алёной 02.09.2026 из десяти вариантов.
     Девять остальных убраны вместе с переключателем.
     Размер поднят: настоящее курсивное начертание Cormorant заметно мельче
     поддельного наклона, которым браузер обходился раньше, и на прежнем
     кегле строка выглядела мелкой. */
  .hs-b{
    font-family:"Cormorant Garamond",Georgia,serif;font-style:italic;
    font-size:clamp(1.32rem,2.85vw,1.86rem);line-height:1.4;
    color:var(--ink);
  }
  section{padding:52px 0}
  /* Первая секция стоит ближе к цитате: она — её продолжение, а не новый блок. */
  main#home > .wrap > section:first-of-type{padding-top:22px}
  .eyebrow{
    font-size:.76rem;letter-spacing:.16em;text-transform:uppercase;
    color:var(--muted);display:flex;align-items:center;gap:12px;margin-bottom:22px;
  }
  .eyebrow::after{content:"";flex:1;height:1px;background:var(--line)}

  /* Картинка живёт в псевдоэлементе: так она может приближаться внутри рамки,
     а сама рамка остаётся на месте и не наезжает на соседей. */
  .ph{
    position:relative;border-radius:var(--radius);overflow:hidden;
    background-color:var(--accent-soft);
    box-shadow:var(--lift);
    transition:box-shadow .35s ease, transform .5s cubic-bezier(.22,.68,.3,1);
  }
  .ph::before{
    content:"";position:absolute;inset:0;
    background-image:var(--g);background-size:cover;background-position:center;
    transition:transform .55s cubic-bezier(.22,.68,.3,1);
  }
  /* Выбранный эффект: приближается вся плитка, поверх соседей. */
  .ph:hover{box-shadow:var(--lift-hi);transform:scale(1.045);z-index:3}

  /* внутри обложки тень не нужна — её несёт сама обложка */
  .album .cover .ph{box-shadow:none;border-radius:0}
  .album .cover{box-shadow:var(--lift);transition:box-shadow .35s ease, transform .5s cubic-bezier(.22,.68,.3,1);border-radius:var(--radius)}
  .album:hover .cover,.album:focus-visible .cover{box-shadow:var(--lift-hi);transform:scale(1.045);z-index:3}

  

  /* ---- фон-обои: волны с параллаксом ---- */
  .sitebg{--bgimg:url(/assets/bg.jpg)}
  /* Чем выше слой, тем сильнее cover увеличивает картинку и тем больше
     срезается сверху и снизу. Держим его почти вровень с экраном. */
  .sitebg{
    /* Слой обязан быть выше экрана НА ВЕЛИЧИНУ ХОДА, иначе при прокрутке
       снизу открывается щель и сквозь неё виден фон страницы — светлая
       полоса, которую Алёна и заметила 09.09.2026. Считать так: запас
       снизу = height - 100vh + top. Было 110vh при top:-6vh — запас 4vh,
       а ход параллакса 5.5vh, то есть на 1.5vh больше запаса.
       Стало 118vh при top:-8vh — запас 10vh, вдвое больше хода. */
    position:fixed;left:0;right:0;top:-8vh;height:118vh;z-index:-2;
    background-image:var(--bgimg);
    background-size:cover;background-position:center center;
    will-change:transform;
  }
  /* Ролик лежит поверх статичной картинки — она же и запасной вариант,
     если видео не проигралось или у зрителя выключены анимации. */
  .sitebg video{
    position:absolute;inset:0;width:100%;height:100%;
    object-fit:cover;display:block;
  }
  [data-motion="still"] .sitebg video{display:none}
  @media (prefers-reduced-motion:reduce){ .sitebg video{display:none} }
  .veil{
    position:fixed;inset:0;z-index:-1;
    background:linear-gradient(to bottom, var(--veil-top) 0, var(--veil) 62vh, var(--veil) 100%);
  }
  @media (prefers-reduced-motion:reduce){ .sitebg{top:0;height:100vh;transform:none !important} }

  /* Бесконечная лента: две дорожки едут справа налево, их можно тащить рукой.
     Во всю ширину окна, а не по колонке текста — движение так читается лучше. */
  /* Лента обязана обрезать содержимое по бокам, но обрезает и по вертикали —
     вместе с тенью. Даём ей поля сверху и снизу, чтобы тень попадала внутрь
     видимой области, и гасим эти поля отрицательными отступами, чтобы
     расстояния на странице не поехали. */
  .marquee{
    width:100vw;margin-left:calc(50% - 50vw);
    padding:26px 0;margin-top:-26px;margin-bottom:-26px;
    overflow:hidden;cursor:grab;contain:paint;
    /* Горизонтальный жест забираем себе, вертикальный оставляем странице.
       Без этого браузер на телефоне считает любое движение пальцем началом
       прокрутки, шлёт pointercancel — и перетаскивание обрывается через
       пару миллиметров (замечание Алёны 07.09.2026). */
    touch-action:pan-y;
    -webkit-user-select:none;user-select:none;
    -webkit-mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);
    mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);
  }
  .marquee.dragging{cursor:grabbing}
  /* Соседние отрицательные отступы не складываются — берётся больший по модулю.
     Поэтому здесь не «-26 + 14», а сразу итог: 26 - 38 + 26 = 14 px зазора. */
  .marquee + .marquee{margin-top:-38px}
  /* Автоход ленты идёт CSS-анимацией, а не покадровым JS. Причина: CSS-
     анимация transform живёт на композиторе и продолжает идти ровно, даже
     когда главный поток занят разбором картинок или прокруткой. На телефоне
     прежний вариант шёл заметными рывками (замечание Алёны 07.09.2026).
     Перетаскивание рукой сидит на отдельной обёртке .mq-drag, поэтому два
     сдвига складываются и не спорят друг с другом. */
  .mq-drag{will-change:transform}
  .mq-track{display:flex;gap:14px;will-change:transform;animation:mqmove linear infinite}
  .mq-track.still{animation:none}
  @keyframes mqmove{
    from{transform:translate3d(0,0,0)}
    to{transform:translate3d(calc(-1 * var(--mq-period,0px)),0,0)}
  }
  .mq-track .ph{flex:0 0 auto;height:236px;aspect-ratio:3/4;box-shadow:var(--lift-mq)}
  .mq-track .ph:hover{box-shadow:var(--lift-mq-hi)}
  /* Подпись плитки — название альбома, только при наведении.
     Под ней градиент: без него светлый кадр съедает белый текст. */
  .mq-track .ph::after{
    content:"";position:absolute;inset:0;pointer-events:none;
    opacity:0;transition:opacity .35s ease;
    background:linear-gradient(0deg,rgba(4,18,14,.62),transparent 42%);
  }
  .mq-track .ph:hover::after{opacity:1}
  .mq-track .label{
    position:absolute;left:10px;right:10px;bottom:9px;z-index:2;pointer-events:none;
    font-size:9.5px;letter-spacing:.24em;text-transform:uppercase;line-height:1.35;
    color:#fff;text-shadow:0 1px 6px rgba(4,18,14,.9);
    opacity:0;transform:translateY(5px);transition:opacity .35s ease,transform .35s ease;
  }
  .mq-track .ph:hover .label{opacity:1;transform:none}
  .mq-track .ph::before{transition:transform .55s cubic-bezier(.22,.68,.3,1)}

  /* Колонки подбираются по ширине, а не по точкам перелома:
     так сетка не схлопывается в столбик, сколько бы альбомов ни было. */
  .albums{display:grid;grid-template-columns:repeat(auto-fill,minmax(248px,1fr));gap:26px}
  .album{
    display:flex;flex-direction:column;gap:12px;text-align:left;
    border-radius:var(--radius);
  }
  .album .cover{position:relative;aspect-ratio:4/5;border-radius:var(--radius);overflow:hidden}
  .album .cover .ph{position:absolute;inset:0}
  .album.locked .ph{filter:blur(17px) saturate(.65);transform:scale(1.14)}
  .lockbadge{
    position:absolute;inset:0;display:flex;flex-direction:column;
    align-items:center;justify-content:center;gap:10px;
    background:rgba(14,21,18,.34);color:#fff;
  }
  .lockbadge span{font-size:.74rem;letter-spacing:.16em;text-transform:uppercase}

  /* Метка свежего альбома: гаснет сама через неделю после съёмки. */
  .badge-new{
    position:absolute;top:10px;left:10px;z-index:3;
    display:inline-flex;align-items:center;gap:7px;
    padding:5px 11px 5px 9px;border-radius:99px;
    background:rgba(10,18,14,.5);
    -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
    color:#fff;font-size:.63rem;letter-spacing:.15em;text-transform:uppercase;
  }
  .badge-new i{
    width:7px;height:7px;border-radius:50%;background:#F3C34F;
    animation:glow 2.4s ease-out infinite;
  }
  @keyframes glow{
    0%{box-shadow:0 0 0 0 rgba(243,195,79,.75)}
    70%{box-shadow:0 0 0 10px rgba(243,195,79,0)}
    100%{box-shadow:0 0 0 0 rgba(243,195,79,0)}
  }
  @media (prefers-reduced-motion:reduce){
    .badge-new i{animation:none;box-shadow:0 0 8px rgba(243,195,79,.8)}
  }
  .album h3{font-size:var(--step-1)}
  .album .meta{font-size:.85rem;color:var(--muted);display:flex;gap:10px;align-items:center}
  .dot{width:3px;height:3px;border-radius:50%;background:var(--muted);display:inline-block}
  .tag{
    font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
    color:var(--accent);background:var(--accent-soft);
    padding:3px 8px;border-radius:3px;
  }

  /* Возврат к списку — самостоятельная кнопка, а не строчка текста:
     внутри альбома это единственный выход, и он должен читаться сразу. */
  /* Возврат к списку — заметный, но негромкий: подложка едва угадывается,
     чтобы кнопка не спорила с названием альбома под ней. */
  .back{
    display:inline-flex;align-items:center;gap:9px;
    padding:8px 17px 8px 12px;margin:26px 0 22px;
    border-radius:99px;
    border:1px solid color-mix(in srgb, var(--line) 60%, transparent);
    background:color-mix(in srgb, var(--surface) 26%, transparent);
    -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
    color:var(--muted);font-size:.85rem;font-weight:500;
    transition:border-color .18s ease, background .18s ease, color .18s ease;
  }
  .back svg{
    width:16px;height:16px;
    transition:transform .22s cubic-bezier(.2,.7,.3,1);
  }
  .back:hover,.back:focus-visible{
    color:var(--ink);
    border-color:color-mix(in srgb, var(--accent) 55%, transparent);
    background:color-mix(in srgb, var(--surface) 55%, transparent);
  }
  .back:hover svg,.back:focus-visible svg{transform:translateX(-4px)}
  .albumhead{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;margin-bottom:30px}
  .albumhead h2{font-size:var(--step-4);font-weight:300}
  /* Низ альбома: кнопка по центру, под ней строка мелким. Отбита сверху
     заметнее, чем зазор в сетке, — иначе читается как ещё одна плитка. */
  .albumfoot{
    display:flex;flex-direction:column;align-items:center;gap:12px;
    margin:46px 0 8px;text-align:center;
  }
  .albumfoot .btn{padding:14px 30px;font-size:1rem}
  .albumfoot-note{color:var(--muted);font-size:.85rem;margin:0}
  .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px}
  .grid .ph{aspect-ratio:3/4}

  .btn{
    background:var(--accent);color:var(--on-accent);
    padding:12px 22px;border-radius:var(--radius);
    font-weight:500;font-size:.95rem;
    display:inline-flex;align-items:center;gap:9px;
    transition:filter .15s ease;
  }
  .btn:hover,.btn:focus-visible{filter:brightness(1.08)}

  .gate{
    background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
    padding:34px;max-width:430px;margin:34px auto;text-align:center;box-shadow:var(--shadow);
  }
  .gate h2{font-size:var(--step-2);margin-bottom:8px}
  .gate p{color:var(--muted);font-size:.92rem;margin:0 0 20px}
  .gate input{
    font:inherit;font-size:1.3rem;letter-spacing:.35em;text-align:center;
    width:100%;padding:12px;margin-bottom:14px;
    background:var(--bg);color:var(--ink);
    border:1px solid var(--line);border-radius:var(--radius);
  }
  .gate input:focus{outline:2px solid var(--accent);outline-offset:1px}
  .gate .err{color:#C2453B;font-size:.85rem;height:1.2em;margin:8px 0 0}

  .about-me{--g:url(/assets/about-me.jpg)}
  .about{display:grid;grid-template-columns:1fr 1.3fr;gap:52px;align-items:start}
  .about .ph{aspect-ratio:4/5}
  .about p{color:var(--muted);margin:0 0 16px}
  .about p.lead{color:var(--ink);font-size:var(--step-1)}

  /* Связаться. Слева живые адреса, справа форма — человеку должно хватить
     любого из двух: кто-то пишет письмо сам, кто-то не хочет открывать почту. */
  .contact{display:grid;grid-template-columns:1fr 1.1fr;gap:52px;align-items:start}
  .contact p{color:var(--muted);margin:0 0 16px}
  .contact .lines{display:flex;flex-direction:column;gap:12px;margin-top:22px}
  .contact .lines a{
    color:var(--ink);align-self:flex-start;
    border-bottom:1px solid var(--line);padding-bottom:3px;
    transition:color .15s ease,border-color .15s ease;
  }
  .contact .lines a:hover,.contact .lines a:focus-visible{
    color:var(--accent);border-color:var(--accent);
  }
  .cform{display:grid;gap:12px}
  .cform input,.cform textarea{
    font:inherit;width:100%;padding:12px 14px;
    background:var(--surface);color:var(--ink);
    border:1px solid var(--line);border-radius:var(--radius);
  }
  .cform textarea{resize:vertical;min-height:118px}
  .cform input:focus,.cform textarea:focus{outline:2px solid var(--accent);outline-offset:1px}
  .cform .btn{justify-self:start;cursor:pointer}
  .cform .ok{color:var(--accent);font-size:.9rem;margin:0}

  /* Блок с лентой инстаграма был здесь и убран 31.08.2026: решили не ставить
     витрину-имитацию, а сделать настоящую ленту — своими силами, без чужих
     виджетов. Код лежит в журнале проекта, если понадобится вернуть. */

  footer.site{border-top:1px solid var(--line);padding:34px 0 60px;color:var(--muted);font-size:.85rem}
  footer.site .row{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}

  /* Окно может оказаться выше экрана — на телефоне это и происходило:
     верх и низ обрезались, прокрутить было нечем. Подложка сама стала
     прокручиваемой, а окно центрируется полями (margin:auto), а не
     align-items: при переполнении центрирование флексом срезает верх. */
  .scrim{
    position:fixed;inset:0;z-index:60;display:none;
    justify-content:center;padding:24px;overflow-y:auto;
    -webkit-overflow-scrolling:touch;overscroll-behavior:contain;
    background:rgba(14,21,18,.5);backdrop-filter:blur(3px);
  }
  .scrim.on{display:flex}
  .scrim .modal{margin:auto}
  .modal{
    background:var(--surface);border-radius:8px;box-shadow:var(--shadow);
    max-width:760px;width:100%;padding:30px;position:relative;
    display:grid;grid-template-columns:248px 1fr;gap:28px;align-items:stretch;
    animation:rise .28s cubic-bezier(.2,.7,.3,1);
  }

  .modal-shot{--g:url(/assets/koko-head.jpg)}
  /* Снимок мечты появляется чуть позже самого окна — сначала читается текст,
     потом рядом проявляется то, ради чего всё затевается. */
  .modal-shot{
    background-image:var(--g);background-size:cover;background-position:center;
    border-radius:6px;min-height:330px;
    animation:shotin .9s .7s cubic-bezier(.2,.72,.28,1) both;
  }
  @keyframes shotin{
    from{opacity:0;transform:translateX(-16px) scale(.965)}
    to{opacity:1;transform:none}
  }
  @media (prefers-reduced-motion:reduce){ .modal-shot{animation:none} }
  @media (max-width:640px){
    .scrim{padding:12px}
    .modal{grid-template-columns:1fr;gap:16px;padding:22px 20px 24px}
    /* Снимок мечты показываем целиком, а не обрезанным по центру: держим
       родную пропорцию кадра (2197×3213) и ограничиваем высотой экрана,
       ширина подстраивается сама. */
    /* Высоту задаём явно, ширину считает пропорция. Наоборот не выйдет:
       у grid-элемента с margin:auto ширина берётся от содержимого, а фону
       содержимого нет — блок схлопывался в ноль. */
    .modal-shot{
      min-height:0;height:min(30vh,232px);width:auto;
      aspect-ratio:2197/3213;justify-self:center;
      background-size:contain;background-repeat:no-repeat;
    }
    .modal h2{font-size:1.5rem;margin-bottom:10px}
    .modal p{font-size:.9rem}
    .amounts{gap:7px;margin:16px 0 8px}
    .amounts button{padding:10px 0;font-size:.92rem}
  }
  @keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
  @media (prefers-reduced-motion:reduce){
    .modal{animation:none}
    .ph,.ph::before,.album .cover{transition:none}
    .ph:hover,.album:hover .cover{transform:none}
  }
  .modal h2{font-size:var(--step-2);margin-bottom:14px}
  .modal p{color:var(--muted);font-size:.94rem;margin:0 0 12px}
  .modal p.dream{color:var(--ink)}
  /* Первая строка крупнее и плотнее остального текста, но заметно мельче
     заголовка: в окне по кнопке заголовка нет, и держать начало приходится
     ей. Полуторного веса хватает — жирнее спорило бы с суммами. */
  .modal p#modalLead{color:var(--ink);font-size:1.06rem;font-weight:500;line-height:1.5;margin-bottom:14px}
  /* Реквизиты: название способа приглушено, сам ник — обычным цветом,
     каждый на своей строке. Так их удобно переписывать в приложение. */
  /* Реквизиты для прямых переводов — свёрнуты. Окно про деньги должно
     вести к одному действию; способы «мимо Ko-fi» нужны меньшинству,
     поэтому они за одной строкой, а не тремя. */
  details.pays{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
  details.pays > summary{
    list-style:none;cursor:pointer;
    font-size:.95rem;color:var(--muted);
  }
  details.pays > summary::-webkit-details-marker{display:none}
  details.pays > summary::after{content:' ›';display:inline-block;transition:transform .18s ease}
  details.pays[open] > summary::after{transform:rotate(90deg)}
  details.pays > summary:hover{color:var(--ink)}
  .paylist{margin:10px 0 0;padding:0;border:0}
  .modal p.pays span,.modal .paylist span{display:block;margin-top:4px}
  .modal p.pays em,.modal .paylist em{font-style:normal;opacity:.72;margin-right:6px}
  .modal p.pays b,.modal .paylist b{color:var(--ink);font-weight:600;word-break:break-word}
  .modal .close{position:absolute;top:12px;right:14px;color:var(--muted);font-size:1.4rem;line-height:1}
  .modal .close:hover{color:var(--ink)}
  .amounts{display:flex;gap:9px;margin:20px 0 8px}
  .amounts button{
    flex:1;border:1px solid var(--line);border-radius:var(--radius);
    padding:12px 0;text-align:center;font-weight:500;
    font-variant-numeric:tabular-nums;transition:.15s ease;
  }
  .amounts button:hover,.amounts button:focus-visible{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  /* Выбранная сумма держится заливкой, а не только рамкой: рамку на тёмном
     фоне легко не заметить, а выбор должен читаться с одного взгляда. */
  .amounts button[aria-pressed="true"]{
    border-color:var(--accent);background:var(--accent);color:var(--on-accent);
  }
  /* Поле своей суммы. Знак доллара — частью поля, чтобы не пришлось вводить
     его руками и гадать, нужен он или нет. */
  .ownsum{
    display:flex;align-items:center;gap:2px;margin:10px 0 0;
    border:1px solid var(--line);border-radius:var(--radius);
    padding:0 12px;background:var(--surface);
  }
  /* Свой display перебивает браузерное [hidden]{display:none} — без этой
     строки скрытое поле продолжает показываться. */
  .ownsum[hidden]{display:none}
  .ownsum:focus-within{border-color:var(--accent)}
  .ownsum .cur{color:var(--muted)}
  .ownsum input{
    font:inherit;color:var(--ink);background:none;border:0;outline:none;
    padding:12px 4px;width:100%;font-variant-numeric:tabular-nums;
  }
  /* Стрелки-крутилки у числового поля только мешают: сумму набирают целиком. */
  .ownsum input::-webkit-outer-spin-button,
  .ownsum input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
  .ownsum input[type=number]{-moz-appearance:textfield}
  .modal .btn.send{
    width:100%;justify-content:center;margin-top:14px;
    padding:14px 0;font-size:1rem;
  }
  .modal .btn.send[disabled]{
    background:none;border:1px solid var(--line);color:var(--muted);
    cursor:default;font-weight:400;
  }
  .sendnote{font-size:.78rem;color:var(--muted);margin:15px 0 0;text-align:center}
  .alt{font-size:.82rem;color:var(--muted);margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
  .alt b{color:var(--ink);font-weight:500}

  .fund{margin-top:22px}
  .fund .nums{
    display:flex;justify-content:space-between;align-items:baseline;gap:12px;
    font-size:.8rem;color:var(--muted);margin-bottom:9px;
    font-variant-numeric:tabular-nums;
  }
  .fund .nums .label{letter-spacing:.1em;text-transform:uppercase;font-size:.72rem}
  .fund .amount{display:inline-flex;align-items:baseline;gap:6px}
  .fund .amount b{color:var(--accent);font-weight:700;font-size:1.5rem;line-height:1}
  .fund .amount em{font-style:normal;font-size:1rem;color:var(--muted)}
  .fund-date{
    margin-top:9px;font-size:.79rem;color:var(--muted);
    display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;
  }
  .fund-date b{color:var(--ink);font-weight:500}
  .fund-date .left{color:var(--accent);font-variant-numeric:tabular-nums}
  .track{height:7px;background:var(--accent-soft);border-radius:99px;overflow:hidden}
  /* Ширина шкалы = собрано / цель: 217 из 2000 — это 10.85 %.
     Меняются суммы — пересчитать и здесь. */
  .track i{display:block;height:100%;width:10.85%;background:var(--accent);border-radius:99px}

  .pill{
    position:fixed;right:22px;bottom:22px;z-index:50;display:none;
    background:var(--surface);color:var(--ink);
    border:1px solid var(--line);box-shadow:var(--shadow);
    border-radius:99px;padding:11px 18px;font-size:.88rem;
    align-items:center;gap:9px;
  }
  .pill.on{display:inline-flex}
  .pill:hover{border-color:var(--accent);color:var(--accent)}
  .pill svg{color:var(--accent)}

  .note{
    position:fixed;left:22px;bottom:22px;z-index:50;
    background:var(--ink);color:var(--bg);
    border-radius:var(--radius);padding:9px 14px;font-size:.78rem;line-height:1.45;max-width:270px;
  }
  .note b{font-weight:700}

  /* ---- лайтбокс ---- */
  .lb{
    position:fixed;inset:0;z-index:70;display:none;
    align-items:center;justify-content:center;
    background:rgba(10,16,13,.86);backdrop-filter:blur(4px);
    padding:clamp(12px,3vw,40px);
  }
  .lb.on{display:flex}
  .lb-frame{
    position:relative;width:100%;height:100%;
    display:flex;align-items:center;justify-content:center;
  }
  /* Именно <img>, а не фон: у картинки-фона элемент занимает весь экран,
     и клик по видимой пустоте попадает в него — закрыть щелчком мимо
     становится невозможно. */
  .lb-img{
    max-width:100%;max-height:100%;
    display:block;object-fit:contain;
    animation:lbin .52s cubic-bezier(.19,.78,.28,1) both;
    touch-action:pan-y;
  }
  .lb-img.slide{animation:lbslide .34s cubic-bezier(.22,.72,.3,1) both}
  @keyframes lbin{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:none}}
  @keyframes lbslide{from{opacity:0;transform:translateX(var(--from,18px))}to{opacity:1;transform:none}}
  .lb-nav{
    position:absolute;top:50%;transform:translateY(-50%);
    width:52px;height:52px;
    color:rgba(255,255,255,.82);
    display:flex;align-items:center;justify-content:center;
    transition:color .18s ease, transform .18s ease;
  }
  .lb-nav svg{width:26px;height:26px}
  .lb-nav:hover{color:#fff}
  .lb-prev{left:calc(50% - min(46vw, 640px) - 4px)}
  .lb-next{right:calc(50% - min(46vw, 640px) - 4px)}
  .lb-prev:hover{transform:translateY(-50%) translateX(-3px)}
  .lb-next:hover{transform:translateY(-50%) translateX(3px)}
  @media (max-width:820px){
    .lb-prev{left:2px} .lb-next{right:2px}
    .lb-nav{width:40px;height:40px}
  }
  .lb-close{
    position:fixed;top:18px;right:22px;color:rgba(255,255,255,.75);
    font-size:2rem;line-height:1;z-index:71;
  }
  .lb-close:hover{color:#fff}
  .lb-count{
    position:fixed;bottom:20px;left:50%;transform:translateX(-50%);
    color:rgba(255,255,255,.7);font-size:.82rem;letter-spacing:.1em;
    font-variant-numeric:tabular-nums;
  }
  .grid .ph{cursor:zoom-in}

  /* ---- выбор кадров ---- */
  .pick{
    position:absolute;top:9px;right:9px;z-index:4;
    width:26px;height:26px;border-radius:50%;
    border:2px solid rgba(255,255,255,.9);
    background:rgba(10,18,14,.32);
    -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
    display:flex;align-items:center;justify-content:center;
    opacity:0;transition:opacity .18s ease, background .18s ease, border-color .18s ease;
  }
  .pick svg{width:14px;height:14px;color:#fff;opacity:0;transition:opacity .18s ease}
  .grid .ph:hover .pick,.grid .ph:focus-within .pick,.ph.picked .pick{opacity:1}
  .ph.picked .pick{background:var(--accent);border-color:var(--accent)}
  .ph.picked .pick svg{opacity:1}
  .ph.picked{outline:3px solid var(--accent);outline-offset:2px}

  /* Панель выбора — в том же негромком ключе, что кнопка возврата:
     подложка сквозная, цвет берут только границы и наведение. */
  .selbar{
    position:fixed;left:50%;bottom:22px;transform:translateX(-50%);
    z-index:55;display:none;align-items:center;gap:6px;
    border-radius:99px;padding:8px 9px 8px 19px;font-size:.88rem;
    border:1px solid color-mix(in srgb, var(--line) 60%, transparent);
    background:color-mix(in srgb, var(--surface) 40%, transparent);
    -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
    box-shadow:var(--lift-mq);
  }
  .selbar.on{display:flex}
  .selbar .count{color:var(--muted);margin-right:8px;font-variant-numeric:tabular-nums}
  .selbar .go{
    padding:8px 17px;border-radius:99px;font-weight:500;font-size:.86rem;
    color:var(--ink);
    border:1px solid color-mix(in srgb, var(--accent) 45%, transparent);
    background:color-mix(in srgb, var(--surface) 30%, transparent);
    transition:border-color .18s ease, background .18s ease;
  }
  .selbar .go:hover,.selbar .go:focus-visible{
    border-color:var(--accent);
    background:color-mix(in srgb, var(--accent-soft) 70%, transparent);
  }
  .selbar .plain{
    color:var(--muted);padding:8px 13px;border-radius:99px;font-size:.85rem;
    transition:color .18s ease, background .18s ease;
  }
  .selbar .plain:hover,.selbar .plain:focus-visible{
    color:var(--ink);
    background:color-mix(in srgb, var(--surface) 45%, transparent);
  }
  @media (max-width:520px){
    .selbar{left:14px;right:14px;transform:none;justify-content:space-between;padding-left:16px}
  }

  .lb-save{
    position:fixed;top:20px;right:70px;z-index:71;
    color:rgba(255,255,255,.75);display:flex;align-items:center;gap:7px;
    font-size:.82rem;
  }
  .lb-save:hover{color:#fff}
  .lb-save svg{width:17px;height:17px}
  @media (prefers-reduced-motion:reduce){ .lb-img{animation:none} }
  .note .x{opacity:.6;position:absolute;top:6px;right:9px}
  .note{position:fixed;padding:11px 14px 12px}
  .bgpick{display:flex;align-items:center;gap:5px;margin-top:9px;flex-wrap:wrap}
  /* Кнопки были рассчитаны на цифры (23×23), а подписи стали словами —
     они налезали друг на друга. Ширина по содержимому. */
  .bgpick button{
    min-width:23px;height:23px;padding:0 7px;white-space:nowrap;border-radius:4px;
    background:rgba(255,255,255,.14);color:inherit;
    font-size:.76rem;line-height:1;font-variant-numeric:tabular-nums;
  }
  .bgpick button:hover{background:rgba(255,255,255,.3)}
  .bgpick button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);font-weight:700}
  .bgname{opacity:.75;margin-top:6px;font-size:.74rem}
  .hoverpick{display:flex;align-items:center;gap:5px;margin-top:8px;flex-wrap:wrap}
  .hoverpick button{
    padding:3px 9px;border-radius:4px;font-size:.74rem;
    background:rgba(255,255,255,.14);color:inherit;
  }
  .hoverpick button:hover{background:rgba(255,255,255,.3)}
  .hoverpick button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);font-weight:700}

  .view{display:none}
  .view.on{display:block}

  /* Телефон, повёрнутый набок. Здесь мало не ширины, а ВЫСОТЫ: логотип,
     посчитанный от ширины окна, занимал почти весь экран и наезжал на
     цитату (замечание Алёны 07.09.2026). Поэтому размер считаем от высоты,
     а ширину выводит пропорция. Запрос идёт первым — правила ниже
     (max-width:820px) в горизонтали телефона тоже подходят по ширине,
     и они должны перебиваться этим блоком... поэтому он повторён после них. */
  @media (max-width:820px){
    :root{--sub-bottom:clamp(64px,14vh,140px)}
    /* На узком экране имя занимает почти всю ширину — иначе оно теряется. */
    .wordmark{width:78vw}
    .mq-track .ph{height:170px}
    .albums{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:18px}
    .grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
    .about{grid-template-columns:1fr}
    .contact{grid-template-columns:1fr;gap:30px}
    .note{display:none}
  }

  /* ---- телефон ----
     Шапка: логотип садится слева, ссылки жмутся вправо, и на узкой полосе
     они наезжали друг на друга. Уменьшаем разрядку и кегль меню, поля
     страницы, а на совсем узких экранах убираем «Work» — он ведёт наверх,
     ровно туда же, куда и сам логотип в шапке. */
  @media (max-width:640px){
    .wrap{padding:0 16px}
    /* Пунктов стало три, и им можно вернуть воздух. */
    nav.links{gap:17px;font-size:.66rem;letter-spacing:.13em}
    .bar{gap:12px}
  }

  /* Телефон набок: размер логотипа от высоты, а не от ширины. Блок стоит
     после «max-width:820px» намеренно — в горизонтали подходят оба, и
     побеждать должен этот. */
  @media (max-height:560px) and (orientation:landscape){
    :root{--sub-bottom:clamp(46px,11vh,78px)}
    .wordmark{width:auto;height:min(40svh,168px)}
    .hero{min-height:calc(100svh - 48px)}
    .hero-sub{font-size:.95rem}
  }

  /* Альбомы на телефоне — две колонки (её решение 07.09.2026; список
     пробовали, не понравился). Подписи уходят под обложку и разносятся
     по строкам: название, ниже дата, ниже число кадров. В узкой колонке
     строка «August 2026 · 11 photos» всё равно не помещалась целиком —
     точка-разделитель здесь убрана, вместо неё перевод строки. */
  @media (max-width:560px){
    .albums{grid-template-columns:repeat(2,1fr);gap:14px 12px}
    .album{gap:8px}
    .album h3{font-size:1rem;line-height:1.25;text-wrap:balance}
    .album .meta{
      flex-direction:column;align-items:flex-start;gap:2px;
      font-size:.78rem;line-height:1.35;
    }
    .album .meta .dot{display:none}
    .album .meta .tag{margin-top:2px}
    .badge-new{top:7px;left:7px;padding:4px 9px 4px 7px}
  }

/* ---- сайт: картинки файлами, а не фоном ----
   В сетке альбома кадры вставлены как <img loading="lazy"> — там их бывает
   полсотни, и грузить все сразу незачем. Плитка ведёт себя как прежняя:
   изображение обрезается по рамке и приближается при наведении. */
.ph > img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;
  transition:transform .55s cubic-bezier(.22,.68,.3,1);
}
.ph:hover > img{transform:scale(1.055)}
[data-hover="tile"] .ph:hover > img{transform:none}
/* Пока кадр не загрузился, на его месте ровный тон, а не пустой провал. */
.grid .ph{background:color-mix(in srgb, var(--surface) 60%, transparent)}

/* Пусто в разделе альбомов — когда съёмок ещё нет. */
.empty{color:var(--muted);font-size:.95rem;margin:0}