/* ══════════════════════════════════════════════════════════════════════
   МАСТЕРСКАЯ: двенадцать приёмов, невидимых до наведения.

   Раздел живёт в системе studio-v2: те же токены (--lime, --white,
   --muted, --line, --ease), тот же шрифт, те же отступы .section/.wrap.
   Отдельный файл нужен не для отдельного стиля, а чтобы пересборка
   studio-v2.css не стёрла эту работу и наоборот.

   ГЛАВНОЕ ПРАВИЛО РАЗДЕЛА: В ПОКОЕ КАРТА ПОЧТИ ПУСТА. Тонкая кайма, имя
   приёма, приглушённый текст. Свечение, разрезы, обводки, частицы,
   занавес — всё просыпается только под курсором и гаснет за ним.

   Почему не «всё сразу»: двенадцать одновременно работающих эффектов
   складываются в шум, где не виден ни один, и жгут кадр на слабой машине.
   Разложенные по наведению, они дают двенадцать отдельных открытий, а
   считается всегда ровно одна карта — та, где курсор.

   ЧТО НЕ ПРЯЧЕТСЯ. Прячется ПРИЁМ, а не содержимое. Под каждым эффектом
   лежит обычный читаемый текст: с клавиатуры, с телефона и для поиска
   карта полна и без единого наведения.

   КАСАНИЕ. У пальца нет наведения, поэтому те же состояния навешаны на
   :focus-within и на класс .live, который скрипт ставит по касанию и по
   появлению карты в поле зрения на узких устройствах.
   ══════════════════════════════════════════════════════════════════════ */

.craft-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:52px}

.craft{position:relative;isolation:isolate;overflow:hidden;
  min-height:236px;padding:24px;border-radius:18px;
  background:#08080a;border:1px solid var(--line);
  display:flex;flex-direction:column;justify-content:flex-end;gap:9px;
  transition:border-color .4s var(--ease),transform .45s var(--ease),
             box-shadow .45s var(--ease)}
.craft:hover,.craft:focus-within,.craft.live{
  border-color:#c0ff3966;transform:translateY(-4px);
  box-shadow:0 22px 64px #000000b3,0 0 46px #c0ff391a}
.craft h3{font-size:19px;font-weight:750;letter-spacing:-.03em;
  color:var(--white);position:relative;z-index:4}
.craft p{font-size:13.5px;line-height:1.55;color:var(--muted);
  position:relative;z-index:4;max-width:34ch}
.craft .tag{position:absolute;top:17px;right:19px;z-index:4;
  font:500 10.5px/1 Tonavi,sans-serif;letter-spacing:.15em;text-transform:uppercase;
  color:#5b5e57;transition:color .4s var(--ease)}
.craft:hover .tag,.craft.live .tag{color:var(--lime)}

/* ── 01. ПРОЖЕКТОР ────────────────────────────────────────────────────
   Второй слой вырезан круглой маской вокруг курсора. В покое радиус
   ноль — слоя не видно вовсе.
   Надпись стоит в ВЕРХНЕЙ трети: по центру она ложилась на заголовок с
   абзацем, и оба становились нечитаемы. Найдено снимком наведения. */
.c-spot .under{position:absolute;inset:0;z-index:3;padding:26px;
  display:flex;align-items:flex-start;justify-content:center;text-align:center;
  font:750 clamp(20px,2.3vw,29px)/1.15 Tonavi,sans-serif;letter-spacing:-.04em;
  color:var(--lime);pointer-events:none;
  -webkit-mask-image:radial-gradient(circle var(--r,0px) at var(--mx,50%) var(--my,50%),
    #000 0 92%,transparent 100%);
  mask-image:radial-gradient(circle var(--r,0px) at var(--mx,50%) var(--my,50%),
    #000 0 92%,transparent 100%);
  transition:--r .3s var(--ease)}
.c-spot:hover .under,.c-spot.live .under,.c-spot:focus-within .under{--r:132px}

/* ── 02. ЭЛЕКТРИЧЕСКАЯ КАЙМА ──────────────────────────────────────────
   Конический градиент крутится за краем карты и виден полосой в полтора
   пикселя. В покое прозрачность ноль — кайма не горит вовсе. */
.c-edge:before{content:"";position:absolute;left:50%;top:50%;
  width:190%;aspect-ratio:1;translate:-50% -50%;z-index:0;opacity:0;
  background:conic-gradient(from 0deg,transparent 0deg,var(--lime) 42deg,
    #22e0ff 78deg,#ff2f6d 112deg,transparent 170deg,transparent 360deg);
  animation:craft-spin 3.4s linear infinite;transition:opacity .45s var(--ease)}
.c-edge:after{content:"";position:absolute;inset:1.5px;z-index:1;
  border-radius:16.5px;background:#08080a}
.c-edge:hover:before,.c-edge.live:before,.c-edge:focus-within:before{opacity:1}
@keyframes craft-spin{to{rotate:360deg}}

/* ── 03. РАСШИФРОВКА ──────────────────────────────────────────────────
   Стиль только держит ширину, чтобы строка не прыгала при переборе. */
.c-scramble .scr{font:750 clamp(19px,2.1vw,26px)/1.15 Tonavi,sans-serif;
  letter-spacing:0;color:var(--lime);z-index:4;position:relative;
  min-height:1.15em;margin-bottom:6px;font-variant-numeric:tabular-nums}

/* ── 04. ЗАНАВЕС ──────────────────────────────────────────────────────
   Слой стоит наготове, срезанный в ноль.
   z-index 6, а не 3: на 3 он оказывался ПОД заголовком и абзацем карты
   (они на 4), и открытый занавес показывал две надписи внахлёст. */
.c-curtain .curtain{position:absolute;inset:0;z-index:6;padding:24px;
  display:flex;flex-direction:column;justify-content:flex-end;gap:9px;
  background:linear-gradient(158deg,#ff2f6d,#78002f);
  clip-path:inset(100% 0 0 0);transition:clip-path .62s cubic-bezier(.76,0,.18,1)}
.c-curtain:hover .curtain,.c-curtain.live .curtain,
.c-curtain:focus-within .curtain{clip-path:inset(0 0 0 0)}
.c-curtain .curtain b{font-size:19px;font-weight:750;letter-spacing:-.03em;color:#fff}
.c-curtain .curtain span{font-size:13.5px;line-height:1.55;
  color:#ffffffe0;max-width:34ch}

/* ── 05. НАКЛОН И БЛИК ────────────────────────────────────────────────
   Поворот задаёт скрипт; здесь только блик, едущий за курсором. */
.c-tilt{transform-style:preserve-3d}
.c-tilt .glare{position:absolute;inset:0;z-index:3;pointer-events:none;opacity:0;
  background:radial-gradient(260px at var(--mx,50%) var(--my,50%),
    #ffffff29,transparent 66%);transition:opacity .4s var(--ease)}
.c-tilt:hover .glare,.c-tilt.live .glare{opacity:1}
.c-tilt .slab{position:relative;z-index:4;transform:translateZ(38px);
  display:flex;flex-direction:column;gap:9px}

/* ── 06. РАЗРЕЗ ───────────────────────────────────────────────────────
   Два цветных дубля лежат точно под словом и разъезжаются. */
.c-split .word{position:relative;z-index:4;margin-bottom:6px;
  font:750 clamp(21px,2.5vw,31px)/1.05 Tonavi,sans-serif;
  letter-spacing:-.05em;color:var(--white)}
.c-split .word:before,.c-split .word:after{content:attr(data-text);
  position:absolute;left:0;top:0;width:100%;opacity:0;
  transition:transform .18s steps(2),opacity .18s}
.c-split .word:before{color:#ff2f6d;mix-blend-mode:screen}
.c-split .word:after{color:#22e0ff;mix-blend-mode:screen}
.c-split:hover .word:before,.c-split.live .word:before{
  opacity:.92;animation:craft-j1 .34s steps(2) infinite}
.c-split:hover .word:after,.c-split.live .word:after{
  opacity:.92;animation:craft-j2 .29s steps(2) infinite}
@keyframes craft-j1{0%,100%{transform:translate3d(-3px,-2px,0)}50%{transform:translate3d(-6px,1px,0)}}
@keyframes craft-j2{0%,100%{transform:translate3d(3px,2px,0)}50%{transform:translate3d(6px,-1px,0)}}

/* ── 07. ИЗ ТУМАНА ────────────────────────────────────────────────────
   Не «размытое становится чётким», а обесцвеченное набирает краску:
   так видно и фокус, и сам цвет. */
.c-fog .fog{position:absolute;inset:0;z-index:1;
  background:radial-gradient(300px at 22% 26%,var(--lime),transparent 62%),
             radial-gradient(300px at 78% 74%,#ff2f6d,transparent 62%),
             radial-gradient(240px at 54% 52%,#22e0ff,transparent 60%);
  filter:blur(34px) saturate(.3);opacity:.36;
  transition:filter .6s var(--ease),opacity .6s var(--ease)}
.c-fog:hover .fog,.c-fog.live .fog{filter:blur(12px) saturate(1.7);opacity:.88}
.c-fog .slab{position:relative;z-index:4;display:flex;flex-direction:column;gap:9px}

/* ── 08. ВОЛНА ────────────────────────────────────────────────────────
   Кольцо расходится от точки нажатия и удаляется, когда отыграет. */
.c-ripple{cursor:pointer}
.craft-ring{position:absolute;z-index:2;border-radius:50%;pointer-events:none;
  border:1.5px solid var(--lime);translate:-50% -50%;
  animation:craft-wave .72s var(--ease) forwards}
@keyframes craft-wave{from{width:0;height:0;opacity:.85}to{width:540px;height:540px;opacity:0}}

/* ── 09. МАГНИТНОЕ ПОЛЕ ───────────────────────────────────────────────
   Точки разбегаются от курсора. В покое холст притушен. */
.c-field canvas{position:absolute;inset:0;z-index:1;width:100%;height:100%;
  opacity:.28;transition:opacity .45s var(--ease)}
.c-field:hover canvas,.c-field.live canvas{opacity:1}
.c-field .slab{position:relative;z-index:4;display:flex;flex-direction:column;gap:9px}

/* ── 10. ОБВОДКА ──────────────────────────────────────────────────────
   Длина периметра берётся замером у самой фигуры: зашитое число врёт
   при любой смене ширины, и линия либо не доходит, либо обегает дважды. */
.c-stroke .frame{position:absolute;inset:0;z-index:2;pointer-events:none}
.c-stroke .frame rect{fill:none;stroke:var(--lime);stroke-width:1.6;
  stroke-dasharray:var(--len,1300);stroke-dashoffset:var(--len,1300);
  transition:stroke-dashoffset .95s cubic-bezier(.65,0,.2,1)}
.c-stroke:hover .frame rect,.c-stroke.live .frame rect{stroke-dashoffset:0}

/* ── 11. ВСТРЕЧНЫЕ ЛЕНТЫ ──────────────────────────────────────────────
   Две строки ползут в разные стороны; под курсором разворачиваются и
   набирают цвет. Дубль строки нужен, чтобы шов не был виден. */
.c-strips .row{position:absolute;left:0;right:0;z-index:2;overflow:hidden;
  white-space:nowrap;opacity:.14;transition:opacity .45s var(--ease)}
.c-strips .row.r1{top:31%}
.c-strips .row.r2{top:50%}
.c-strips .row i{display:inline-block;font-style:normal;
  font:750 25px/1 Tonavi,sans-serif;letter-spacing:-.03em;
  color:var(--white);padding-right:22px}
.c-strips .row.r1 i{animation:craft-left 15s linear infinite}
.c-strips .row.r2 i{animation:craft-right 18s linear infinite}
.c-strips:hover .row,.c-strips.live .row{opacity:.95}
.c-strips:hover .row.r1 i,.c-strips.live .row.r1 i{animation-direction:reverse;color:var(--lime)}
.c-strips:hover .row.r2 i,.c-strips.live .row.r2 i{animation-direction:reverse;color:#ff2f6d}
@keyframes craft-left{to{transform:translate3d(-50%,0,0)}}
@keyframes craft-right{from{transform:translate3d(-50%,0,0)}to{transform:none}}

/* ── 12. НЕОНОВЫЙ СЛЕД ────────────────────────────────────────────────
   Свет даёт тень, а не подмена шрифта: подмена сдвинула бы строку. */
.c-neon .neon{position:relative;z-index:4;margin-bottom:6px;
  font:750 clamp(21px,2.5vw,31px)/1.05 Tonavi,sans-serif;letter-spacing:-.05em;
  color:var(--white);text-shadow:none;
  transition:color .4s var(--ease),text-shadow .4s var(--ease)}
.c-neon:hover .neon,.c-neon.live .neon{color:var(--lime);
  text-shadow:0 0 6px #c0ff39e6,0 0 22px #c0ff398c,0 0 54px #c0ff394d}
.c-neon .thread{position:absolute;left:24px;right:24px;bottom:78px;height:1px;z-index:3;
  background:linear-gradient(90deg,transparent,var(--lime),transparent);
  transform:scaleX(0);transform-origin:left;
  transition:transform .55s cubic-bezier(.65,0,.2,1)}
.c-neon:hover .thread,.c-neon.live .thread{transform:scaleX(1)}

/* ── узкие экраны ─────────────────────────────────────────────────────── */
@media(max-width:1080px){.craft-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){
  .craft-grid{grid-template-columns:1fr;margin-top:38px}
  .craft{min-height:206px;padding:20px}
  .c-neon .thread{left:20px;right:20px;bottom:72px}
}

/* ── выключенное движение ──────────────────────────────────────────────
   Глушится ХОД, а не показ. Приёмы, чья суть в движении, замирают в
   конечном положении: занавес открыт, обводка дорисована, кайма горит
   неподвижно. Пустых карт не остаётся ни одной — иначе выключенное
   движение превращает раздел в двенадцать чёрных прямоугольников. */
@media(prefers-reduced-motion:reduce){
  .c-edge:before{animation:none;opacity:1;rotate:28deg}
  .c-curtain .curtain{transition:none}
  .c-split .word:before,.c-split .word:after{animation:none;opacity:.85}
  .c-split .word:before{transform:translate3d(-3px,-2px,0)}
  .c-split .word:after{transform:translate3d(3px,2px,0)}
  .c-strips .row i{animation:none}
  .c-strips .row{opacity:.5}
  .c-stroke .frame rect{transition:none;stroke-dashoffset:0;opacity:.55}
  .craft-ring{display:none}
  .craft{transition:none}
  .c-spot .under{--r:150px}
  .c-fog .fog{filter:blur(20px) saturate(1.2);opacity:.6}
}

/* ── ПРАВКА ПО СНИМКУ ПОКОЯ ────────────────────────────────────────────
   Ленты стояли на 31% и 50% высоты и ложились прямо на заголовок с
   абзацем: на снимке «СРОКИ · СМЕТА» перечеркнуло «Встречные ленты».
   Текст карточки прижат к низу, поэтому ленты уводим в верхнюю треть,
   которая у всех карточек пустая. */
.c-strips .row.r1{top:22%}
.c-strips .row.r2{top:38%}

/* ── ПРАВКА ПО ЗАМЕРУ КОНТРАСТА ────────────────────────────────────────
   Бирка приёма стояла цветом #5b5e57 на фоне карточки #08080a: контраст
   3.03 при норме 4.5 для мелкого текста. Двенадцать находок, одна
   причина — цвет выбран на глаз, «чтобы не спорил с заголовком».
   Пересчитан под фон карточки с запасом (ровно 4.50 роняется
   округлением): #787E76 даёт 4.81. */
.craft .tag{color:#787E76}

/* ── СЕТКА ПОРТФОЛИО ЗАКРЫВАЕТСЯ РОВНО НА ЛЮБОЙ ШИРИНЕ ──────────────────
   Полупустой нижний ряд — это не «мало карточек», а некратное число
   ячеек. Замер по ширинам показал, сколько колонок где:
       до 359px — 2,   360–639 — 3,   640–1199 — 4,   от 1200 — 7.
   При 25 проектах и 3 карточках «добавить» всего 28 ячеек: делится на 2,
   на 4 и на 7 без остатка, а на 3 — с остатком 1. Ровно в этой полосе
   внизу висела одинокая карточка.
   Здесь она прячется: 27 ячеек — девять полных рядов по три. */
@media (min-width: 360px) and (max-width: 639px) {
  .portfolio-grid .add-site-card:last-of-type { display: none; }
}

/* ── ПЕРВЫЙ ЭКРАН: УСЛУГА НАЗВАНА КРУПНО ────────────────────────────────
   Слово «САЙТЫ» — главный акцент экрана: 108–183px против 44–72px у
   «ДЕЛАЕМ». Услуга произносится прямо, а не прячется в подзаголовок.
   Стили лежат здесь, а не в studio-v2.css: тот собирается чужим
   конвейером и при пересборке правка исчезла бы молча. */
.sites-message{line-height:.97;letter-spacing:-.065em}.sites-message .hero-kicker{font-size:clamp(44px,4.5vw,72px);letter-spacing:-.055em}.sites-message .hero-sites{font-size:clamp(108px,12.3vw,183px);line-height:1.03;letter-spacing:-.075em}.sites-message .hero-outcome{font-size:clamp(21px,2vw,32px);letter-spacing:-.025em;margin-top:15px;line-height:1.2}.sites-message .hero-sites:after{content:none}.hero-copy{padding-top:35px}.hero-description{margin-top:24px}.hero-layout{min-height:660px}
@media(max-width:800px){.sites-message .hero-kicker{font-size:40px}.sites-message .hero-sites{font-size:105px}.sites-message .hero-outcome{font-size:21px;white-space:normal}.hero-layout{min-height:570px}}
@media(max-width:600px){.sites-message .hero-kicker{font-size:35px}.sites-message .hero-sites{font-size:clamp(91px,27vw,142px)}.sites-message .hero-outcome{font-size:19px;margin-top:9px}.hero-layout{min-height:0}.hero-copy{padding-top:29px}}

/* ── «САЙТЫ.» ДОЛЖНО ВЛЕЗАТЬ В ЭКРАН ────────────────────────────────────
   Замер на 375px: строка при кегле 101.25px требует 388px, а доступно
   335px. Вылезали две последние буквы — «Ы» и точка, правый край 408 при
   окне 375. Отсюда 33px горизонтальной прокрутки на всей странице:
   палец на телефоне тащит её вбок.
   Предельный кегль посчитан, а не подобран: 101.25 × 335 / 388 = 87.4px,
   то есть 23.3vw. Берём 22vw с запасом на другой шрифт и округление.
   Нижняя граница снижена с 91px: при 320px даже 22vw даёт 70px, и
   прежний минимум сам по себе не давал строке влезть. */
@media (max-width: 600px) {
  .sites-message .hero-sites { font-size: clamp(58px, 22vw, 142px); }
}
