@font-face{
  font-family:"Abibas";
  src:url("../assets/fonts/abibas.woff2") format("woff2");
  font-weight:500;
  font-style:normal;
  font-display:swap;
}

/* ============================================================
   ВАРВАЦЫ — портфолио. Одноэкранный блок без прокрутки.

   Вся геометрия снята из макета «Макет сайта 1.svg».
   Система координат макета: 4691x3213. Содержимое занимает
   прямоугольник x 1153..3516, y 535..2504, то есть 2363x1969 —
   это и есть .scene. Все элементы внутри заданы в процентах от
   неё, поэтому композиция масштабируется целиком и не «плывёт».
   ============================================================ */

*,*::before,*::after{ box-sizing:border-box; }

html,body{
  height:100%;
  margin:0;
  overflow:hidden;          /* страница строго в один экран */
}

body{
  font-family:"Inter","Helvetica Neue",Arial,system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;
}

img{ display:block; width:100%; height:auto; user-select:none; }

.defs{ position:absolute; width:0; height:0; }

/* ---------------- Сцена ---------------- */

.stage{
  /* Единственная величина, задающая размер композиции.
     Пропорции взяты из макета: холст 4691x2536, папка занимает по ширине
     44.7% холста, поэтому 44.7vw. Ограничение по высоте не даёт ей
     разрастись на широких и низких экранах. */
  --scene-h:min(calc(44.7vw / 1.63522), 62svh);

  position:relative;
  height:100svh;
  display:grid;
  place-items:center;
  overflow:hidden;
  background:#ffffff;
}

.scene{
  position:relative;
  height:var(--scene-h);
  aspect-ratio:2097.3 / 1282.6;   /* габарит папки с карточками из макета */
  container-type:size;            /* даёт единицы cqw/cqh — 1% сцены */
  perspective:1300px;
  perspective-origin:50% 44%;

  /* Кнопка «Открыть папку» висит под сценой. Сдвигаем композицию вверх на
     половину её выноса, чтобы по центру экрана оказалась группа целиком —
     ровно как в макете, где папка чуть выше середины холста. */
  margin-bottom:calc(0.1728 * var(--scene-h));
}

/* ---------------- Надписи по краям ---------------- */

.mark{
  --mw:clamp(64px, 7.1vw, 148px);
  position:absolute;
  display:block;
  width:var(--mw);
  color:#000;
  z-index:3;
  text-decoration:none;
}
.mark svg{ display:block; width:100%; height:auto; }
/* У путей из макета прописан свой fill="black". Презентационный атрибут
   слабее правила CSS, поэтому перекрываем именно пути, а не элемент svg —
   иначе цвет надписи не поменять. */
.mark svg path,
.cta  svg path{ fill:currentColor; }

/* «о варвацы» длиннее остальных надписей. Ширина коробки задана по её
   собственному viewBox (379.58 против 332.59 у прежней @varvacy), иначе
   буквы вышли бы мельче, чем у соседних надписей. */
.mark--tl{ left:2.70vw;  top:4.25svh; width:calc(var(--mw) * 1.1413); }
.mark--tr{ right:2.60vw; top:4.18svh; }
.mark--bl{ left:2.65vw;  bottom:3.96svh; }

a.mark{ transition:opacity .25s ease; }
a.mark:hover, a.mark:focus-visible{ opacity:.55; outline:none; }

/* ---------------- Пасхалка на «ai creator» ---------------- */

button.mark--egg{
  padding:0;
  border:0;
  background:none;
  color:#000;
  cursor:pointer;
  transition:color .45s ease, opacity .25s ease;
  -webkit-tap-highlight-color:transparent;
}
button.mark--egg:hover,
button.mark--egg:focus-visible{ opacity:.55; outline:none; }
button.mark--egg.is-red{ color:#FF3646; opacity:1; }   /* цвет взят из сердечка */

.heart{
  position:absolute;
  left:50%;
  bottom:10%;
  width:clamp(13px, 1.15vw, 22px);
  height:auto;
  pointer-events:none;
  z-index:5;
  image-rendering:pixelated;    /* пиксель-арт не размывать */
}

/* «Контакты» открывают окно, поэтому это кнопка, а не ссылка.
   Подчёркивание выезжает слева направо — знак, что на неё нажимают. */
.mark__btn{
  position:relative;
  display:block;
  width:100%;
  padding:0;
  border:0;
  background:none;
  color:inherit;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.mark__btn::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:-22%;
  height:clamp(1.5px, .16vw, 3px);
  background:currentColor;
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .34s cubic-bezier(.16, 1, .3, 1);
}
.mark__btn:hover::after,
.mark__btn:focus-visible::after,
.mark__btn[aria-expanded="true"]::after{ transform:scaleX(1); }
.mark__btn:focus-visible{ outline:none; }

/* ---------------- Всплывающие окна у надписей ---------------- */

.pop{
  position:absolute;
  left:0;
  bottom:calc(100% + clamp(14px, 1.4vw, 28px));
  display:flex;
  gap:clamp(10px, 1.1vw, 20px);
  padding:clamp(12px, 1.1vw, 20px);
  background:#fff;
  border:1px solid rgba(0,0,0,.10);
  border-radius:clamp(14px, 1.2vw, 22px);
  box-shadow:0 18px 44px rgba(0,0,0,.14), 0 2px 8px rgba(0,0,0,.05);
  opacity:0;
  transform:translateY(8px) scale(.97);
  transform-origin:left bottom;
  transition:opacity .2s ease, transform .3s cubic-bezier(.16, 1, .3, 1);
}
.pop[hidden]{ display:none; }
.pop.is-open{ opacity:1; transform:none; }

/* Окно «о варвацы» висит у верхнего края экрана, поэтому раскрывается вниз. */
.pop--about{
  top:calc(100% + clamp(14px, 1.4vw, 28px));
  bottom:auto;
  transform:translateY(-8px) scale(.97);
  transform-origin:left top;
  display:block;
  padding:clamp(16px, 1.5vw, 28px) clamp(18px, 1.7vw, 32px);
  width:max-content;
  /* мера строки: длиннее ~34 знаков в строке текст начинает читаться абзацем,
     а это короткая реплика */
  max-width:min(76vw, 30em);
}

/* Тот же приём, что в окне ролика: связный текст — нейтральным шрифтом
   (Abibas акцидентный, абзацем читается тяжело), а ключевые слова —
   фирменным. Прозрачность задана в цвете, а не свойством opacity:
   иначе она погасила бы и выделенные слова вместе с абзацем. */
.pop__text{
  margin:0;
  font-size:clamp(13px, 1.02vw, 18px);
  line-height:1.5;
  color:rgba(11, 11, 11, .6);
}
.pop__text b{
  font-family:"Abibas", "Inter", system-ui, sans-serif;
  font-weight:400;
  font-size:1.08em;      /* у Abibas рост строчных ниже, чем у Inter */
  /* Иначе строки с выделенными словами разъезжаются шире остальных:
     высоту строки задаёт самый рослый инлайн-бокс в ней. */
  line-height:1;
  color:#0B0B0B;
}

.pop__link{
  display:block;
  width:clamp(38px, 3.2vw, 54px);
  border-radius:22%;
  transition:transform .28s cubic-bezier(.16, 1, .3, 1);
}
.pop__link img{ width:100%; height:auto; display:block; }
.pop__link:hover,
.pop__link:focus-visible{ transform:translateY(-4px) scale(1.06); outline:none; }
.pop__link:active{ transform:translateY(-1px) scale(1.01); }


/* ---------------- Кнопка «Открыть папку» ---------------- */

.cta{
  position:absolute;
  left:35.2827%;
  top:110.6736%;      /* ниже габарита папки, расстояние из макета */
  width:29.1988%;
  padding:0;
  border:0;
  background:none;
  color:#000;
  cursor:pointer;
  z-index:12;
  transition:opacity .25s ease, transform .25s ease;
}
.cta svg{ display:block; width:100%; height:auto; }
.cta:hover, .cta:focus-visible{ opacity:.6; outline:none; }
.cta:active{ transform:translateY(1px); }

/* ---------------- Папка ---------------- */

.folder{
  position:absolute;
  inset:0;
  z-index:1;
  transform:rotateX(0deg) rotateY(0deg);
  will-change:transform;
}

.back{
  position:absolute;
  left:15.9543%;
  top:3.4027%;
  width:69.0224%;
}

/* ---------------- Карточки ----------------
   --l/--t — левый верхний угол PNG, --w — его ширина,
   --r — поворот, --ox/--oy — точка поворота: угол самой карточки
   внутри PNG (вокруг PNG есть ~44 px тени, макет считает от тела). */

.card{
  position:absolute;
  left:var(--l);
  top:var(--t);
  width:var(--w);
  z-index:var(--z);            /* порядок наложения постоянный: карточка
                                  поднимается, оставаясь на своём слое */
  transform-origin:var(--ox) var(--oy);

  /* Сдвиг стоит ПЕРЕД поворотом: браузер применяет трансформации справа
     налево, поэтому карточка сначала поворачивается, а поднимается уже
     строго по вертикали экрана — как будто её вынимают из кармана. */
  transform:translate3d(0, 0, 0) rotate(var(--r));

  /* собственный слой: движение остаётся чистым композитингом,
     без перерисовки картинки на каждом кадре */
  will-change:transform;
  backface-visibility:hidden;
  pointer-events:none;         /* курсор ловят области .hit, см. ниже */

  transition:transform 1000ms cubic-bezier(.16, 1, .3, 1);
}

/* Ход карточки ведёт скрипт: он пишет transform в inline-стиль покадрово,
   чтобы подъём доигрывался до конца без прерывания. Переход CSS при этом
   мешал бы, поэтому гасим его. */
.js-cards .card{ transition:none; }

/* ---------------- Области наведения ----------------
   Прямоугольники карточек прямо из макета (поворот вокруг левого верхнего
   угла). Слой НЕПОДВИЖЕН: если бы область поднималась вместе с карточкой,
   она уезжала бы из-под курсора у нижнего края — карточка начинала бы
   дрожать вместо того, чтобы держаться наверху. */

.hits{
  position:absolute;
  inset:0;
  z-index:9;                   /* выше карточек, ниже размытия и стекла */
}

.hit{
  position:absolute;
  padding:0;
  border:0;
  background:none;
  cursor:pointer;
  transform-origin:0 0;
  transform:rotate(var(--r));
  -webkit-tap-highlight-color:transparent;
}
.hit:focus-visible{
  outline:2px solid rgba(0,0,0,.55);
  outline-offset:2px;
}

.h-contest{ left:  0.0000%; top:22.6605%; width:30.2587%; height:65.3960%; --r:-27.2567deg; }
.h-atmo   { left: 34.6600%; top: 0.0001%; width:29.2007%; height:63.1094%; --r:  0deg;       }
.h-music  { left: 18.6631%; top:17.9844%; width:23.7414%; height:51.3107%; --r: -5.1012deg; }
.h-cartoon{ left: 44.0294%; top: 7.3358%; width:28.2060%; height:60.9597%; --r: 11.0884deg; }
.h-anim   { left: 73.6874%; top: 4.9133%; width:29.0737%; height:62.8350%; --r: 25.1724deg; }
.h-logo   { left: 55.8277%; top:24.2207%; width:22.8893%; height:49.4691%; --r:  2.9021deg; }

.c-contest{ --l: -1.9044%; --t:19.4772%; --w:34.0669%; --r:-27.2567deg; --ox:5.5901%; --oy:4.4444%; --z:1; }
.c-atmo   { --l: 32.7952%; --t:-3.0492%; --w:32.9297%; --r:  0deg;      --ox:5.6628%; --oy:4.4044%; --z:2; }
.c-music  { --l: 16.7587%; --t:14.8011%; --w:27.5497%; --r: -5.1012deg; --ox:6.9124%; --oy:5.5288%; --z:3; }
.c-cartoon{ --l: 42.2507%; --t: 4.4271%; --w:31.8053%; --r: 11.0884deg; --ox:5.5925%; --oy:4.3523%; --z:4; }
.c-anim   { --l: 71.8226%; --t: 1.8640%; --w:32.8027%; --r: 25.1724deg; --ox:5.6848%; --oy:4.4221%; --z:5; }
.c-logo   { --l: 54.3865%; --t:21.7948%; --w:25.8136%; --r:  2.9021deg; --ox:5.5829%; --oy:4.4700%; --z:6; }

/* ---------------- Передняя часть папки ----------------
   Непрозрачная картинка с фактурой. Прежнее стекло держалось на
   backdrop-filter, который пересчитывал размытие на каждом кадре и съедал
   17 мс из 16 доступных — отсюда были рывки. Здесь пересчитывать нечего. */

.front{
  position:absolute;
  left:14.5036%;
  top:28.0972%;
  width:71.9609%;
  height:74.5097%;   /* задана явно: непрозрачная область PNG садится точно
                        на контур папки из макета */
  z-index:10;
  pointer-events:none;
}

/* Надписи «ПОРТФОЛИО / ВАРВАЦЫ» — в новой картинке их нет, взяты из макета */
.front-text{
  position:absolute;
  left:22.7435%;
  top:89.8963%;
  width:57.0190%;
  height:auto;
  z-index:11;
  fill:#fff;
  pointer-events:none;
}

/* На узком экране пропорция макета (44.7% ширины холста) дала бы совсем
   маленькую папку — там она занимает почти всю ширину. */
@media (max-width: 900px){
  .stage{ --scene-h:min(calc(92vw / 1.63522), 56svh); }
}

@media (prefers-reduced-motion: reduce){
  .folder{ transform:none !important; }
  .card{ transition:none; }
  .mark, .cta, .pop, .pop__link, .mark__btn::after{ transition:none; }
}

/* на тач-устройствах ховер «залипает» — там подъём не нужен */
@media (hover: none){
  .hit{ cursor:default; }
}

/* ================= Открытая папка ================= */

.fv{
  position:fixed;
  inset:0;
  z-index:50;
  display:grid;
  place-items:center;
  padding:clamp(16px, 6vh, 82px) clamp(16px, 6vw, 132px);
  background:rgba(20,20,22,.26);

  /* Панель не выключается из раскладки: display:none заставлял браузер
     заново считать раскладку и растеризовать её при каждом открытии —
     это и был рывок. Здесь она всегда просчитана, меняется только
     прозрачность, а visibility снимает её с кликов и обхода по Tab. */
  opacity:0;
  visibility:hidden;
  transition:opacity .2s ease, visibility 0s linear .2s;
  will-change:opacity;
}
.fv.is-open{
  opacity:1;
  visibility:visible;
  transition:opacity .2s ease, visibility 0s;
}

.fv__panel{
  position:relative;
  width:min(100%, 1400px);
  height:min(100%, 840px);
  display:grid;
  grid-template-columns:minmax(150px, 15.5%) 1fr;
  grid-template-rows:1fr auto;
  gap:clamp(12px, 1.4vw, 30px);
  padding:clamp(16px, 2vw, 44px);
  background:#fff;
  border-radius:clamp(16px, 1.6vw, 30px);
  box-shadow:0 30px 90px rgba(0,0,0,.22);
  overflow:hidden;
  /* Никакого масштабирования: при нём браузер обязан заново растеризовать
     всю панель с картинками на каждом кадре. Появление держится на одной
     прозрачности — это чистый композитинг. */
}

/* крестик в углу — закрытие */
.fv__close{
  position:absolute;
  left:clamp(16px, 2vw, 44px);
  top:clamp(16px, 2vw, 44px);
  width:clamp(24px, 2.1vw, 42px);
  aspect-ratio:1;
  display:grid;
  place-items:center;
  padding:0;
  border:0;
  background:none;
  color:#0B0B0B;
  cursor:pointer;
  z-index:2;
  transition:transform .22s ease, opacity .22s ease;
}
.fv__close svg{ width:100%; height:100%; display:block; }
.fv__close:hover,
.fv__close:focus-visible{ transform:rotate(90deg); opacity:.6; outline:none; }
.fv__close:active{ transform:rotate(90deg) scale(.94); }

/* ---- столбик фильтров ---- */

.fv__side{
  grid-column:1;
  grid-row:1;
  padding-top:calc(clamp(22px, 1.9vw, 38px) + clamp(14px, 1.6vw, 30px));
  overflow-y:auto;
}

.fv__toggle{
  display:flex;
  align-items:center;
  gap:.5em;
  padding:0;
  border:0;
  background:none;
  color:#111;
  font:400 clamp(15px, 1.6vw, 30px)/1.2 inherit;
  cursor:pointer;
}
.fv__chev{
  width:.62em;
  height:auto;
  transition:transform .28s cubic-bezier(.16, 1, .3, 1);
}
.fv__toggle[aria-expanded="false"] .fv__chev{ transform:rotate(-90deg); }

.fv__filters{
  list-style:none;
  margin:clamp(14px, 1.6vw, 30px) 0 0;
  padding:0;
  display:grid;
  gap:clamp(12px, 1.5vw, 28px);
  overflow:hidden;
}
.fv__toggle[aria-expanded="false"] + .fv__filters{ display:none; }

.fv__filter{
  padding:0;
  border:0;
  background:none;
  color:#111;
  font:700 clamp(15px, 1.8vw, 32px)/1.25 inherit;
  text-align:left;
  cursor:pointer;
  opacity:.5;
  transition:opacity .22s ease;
}
.fv__filter:hover,
.fv__filter:focus-visible{ opacity:.8; outline:none; }
.fv__filter.is-active{ opacity:1; }

/* ---- сетка превью ---- */

.fv__main{
  grid-column:2;
  grid-row:1;
  overflow-y:auto;
  padding-right:4px;
}

.fv__grid{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:clamp(18px, 4.6vw, 96px) clamp(16px, 6.9vw, 140px);
  align-content:start;
}

.tile[hidden]{ display:none; }   /* без этого display:grid ниже перебивает
                                    встроенное скрытие по атрибуту hidden */

.tile{
  padding:0;
  border:0;
  background:none;
  text-align:left;
  cursor:pointer;
  display:grid;
  gap:clamp(7px, .7vw, 14px);
}
.tile__shot{
  display:block;
  aspect-ratio:16 / 9;
  overflow:hidden;
  border-radius:4px;
  background:#000;
}
.tile__shot img{
  width:100%;
  height:100%;
  object-fit:cover;
  display:block;
  transition:transform .5s cubic-bezier(.16, 1, .3, 1), opacity .3s ease;
}
.tile:hover .tile__shot img,
.tile:focus-visible .tile__shot img{ transform:scale(1.05); }
.tile:focus-visible{ outline:none; }
.tile:focus-visible .tile__shot{ box-shadow:0 0 0 2px #000; }

/* Подписи набраны живым текстом фирменным шрифтом. Раньше они вставлялись
   кривыми из макета — файла шрифта не было, и каждое название приходилось
   вынимать оттуда отдельно. */
.tile__cap{
  display:block;
  font-family:"Abibas", "Inter", system-ui, sans-serif;
  font-size:clamp(15px, 1.62vw, 28px);
  line-height:1.15;
  color:#0B0B0B;
  text-align:center;
}

.fv__empty{
  margin:clamp(20px, 3vw, 50px) 0 0;
  color:#111;
  opacity:.45;
  font-size:clamp(14px, 1.1vw, 20px);
}

/* ---- соцсети внизу ---- */

.fv__socials{
  grid-column:1 / -1;
  grid-row:2;
  display:flex;
  justify-content:center;
  gap:clamp(10px, 1vw, 20px);
  padding-top:clamp(6px, .8vh, 16px);
}
.fv__soc{
  display:block;
  width:clamp(34px, 2.6vw, 50px);
  border-radius:22%;
  transition:transform .28s cubic-bezier(.16, 1, .3, 1);
}
.fv__soc img{ width:100%; height:auto; display:block; }
.fv__soc:hover,
.fv__soc:focus-visible{ transform:translateY(-4px) scale(1.05); outline:none; }

@media (max-width: 1100px){
  .fv__grid{ grid-template-columns:repeat(3, 1fr); }
}
@media (max-width: 820px){
  .fv__panel{ grid-template-columns:1fr; grid-template-rows:auto 1fr auto; }
  .fv__side{ grid-column:1; grid-row:1; padding-top:calc(clamp(22px, 1.9vw, 38px) + 14px); }
  .fv__main{ grid-column:1; grid-row:2; }
  .fv__socials{ grid-row:3; }        /* на узком экране рядов три, а не два */
  .fv__filters{ grid-auto-flow:column; grid-auto-columns:max-content; overflow-x:auto; gap:18px; padding-bottom:4px; }
  .fv__grid{ grid-template-columns:repeat(2, 1fr); }
}
@media (max-width: 520px){
  .fv__grid{ grid-template-columns:1fr; }
}

@media (prefers-reduced-motion: reduce){
  .fv, .fv__panel, .tile__shot img, .fv__soc, .fv__chev{ transition:none; }
}

/* ================= Плеер ================= */

.pl{
  position:fixed;
  inset:0;
  z-index:80;
  display:grid;
  place-items:center;
  padding:clamp(14px, 4vh, 56px) clamp(14px, 4vw, 80px);
  background:rgba(8,8,10,.86);

  /* как и у панели: не выключаем из раскладки, чтобы открытие
     не упиралось в пересчёт и первую растеризацию */
  opacity:0;
  visibility:hidden;
  transition:opacity .2s ease, visibility 0s linear .2s;
  will-change:opacity;
}
.pl.is-open{
  opacity:1;
  visibility:visible;
  transition:opacity .2s ease, visibility 0s;
}

.pl__body{
  display:grid;
  grid-template-columns:auto clamp(190px, 21vw, 330px);
  align-items:center;
  gap:clamp(18px, 2.4vw, 48px);
  max-width:100%;
  max-height:100%;
}

/* Окно подгоняется под пропорции конкретного ролика: они у всех разные,
   есть и вертикальные. Ширина считается от доступной высоты, поэтому
   видео всегда влезает целиком и не обрезается. */
.pl__frame{
  --ar:1.7778;
  aspect-ratio:var(--ar);
  /* ширина считается от свободной высоты и с учётом колонки описания справа */
  width:min(60vw, calc(76vh * var(--ar)));
  max-height:76vh;
  background:#000;
  border-radius:clamp(8px, .8vw, 16px);
  overflow:hidden;
  box-shadow:0 30px 90px rgba(0,0,0,.5);
}
.pl__frame video{
  display:block;
  width:100%;
  height:100%;
  object-fit:contain;
  background:#000;
}

.pl__info{
  color:#fff;
  max-height:76vh;
  overflow-y:auto;
}

.pl__title{
  margin:0 0 clamp(8px, 1vh, 16px);
  font-family:"Abibas", "Inter", system-ui, sans-serif;
  font-weight:400;
  font-size:clamp(20px, 1.9vw, 34px);
  line-height:1.15;
}

/* описание — нейтральным шрифтом: Abibas акцидентный, длинный текст
   им читается тяжело */
.pl__desc{
  margin:0;
  font-size:clamp(13px, 1.02vw, 18px);
  line-height:1.5;
  opacity:.72;
}

.pl__close{
  position:absolute;
  top:clamp(14px, 2.4vh, 34px);
  right:clamp(14px, 2vw, 40px);
  width:clamp(26px, 2.2vw, 44px);
  aspect-ratio:1;
  display:grid;
  place-items:center;
  padding:0;
  border:0;
  background:none;
  color:#fff;
  cursor:pointer;
  z-index:2;
  transition:transform .22s ease, opacity .22s ease;
}
.pl__close svg{ width:100%; height:100%; display:block; }
.pl__close:hover,
.pl__close:focus-visible{ transform:rotate(90deg); opacity:.7; outline:none; }

/* на узком экране описание уходит под видео */
@media (max-width: 900px), (orientation: portrait){
  .pl__body{
    grid-template-columns:1fr;
    justify-items:center;
    gap:clamp(12px, 1.6vh, 22px);
  }
  .pl__frame{ width:min(88vw, calc(62vh * var(--ar))); max-height:62vh; }
  .pl__info{ max-width:min(88vw, 560px); text-align:center; max-height:none; }
}

@media (prefers-reduced-motion: reduce){
  .pl, .pl__close{ transition:none; }
}
