
/* ─── герой раздела ─────────────────────────────────────────────────────── */
.vhero{padding:56px 0 30px;text-align:center;position:relative}
.vhero h1{font-family:var(--disp);font-weight:700;letter-spacing:-.03em;
 font-size:clamp(30px,5.4vw,48px);line-height:1.06;max-width:18ch;margin:16px auto 0}
.vhero h1 em{font-style:normal;background:var(--grad);
 -webkit-background-clip:text;background-clip:text;color:transparent}
.vlead{font-size:clamp(14px,2vw,16.5px);font-weight:500;color:var(--ink2);
 max-width:600px;margin:18px auto 0;line-height:1.55}
.vcta{display:inline-flex;align-items:center;gap:9px;margin-top:26px;
 background:var(--grad);color:#fff;font-family:var(--sans);font-weight:800;
 font-size:15.5px;padding:15px 30px;border-radius:14px;border:0;cursor:pointer;
 box-shadow:var(--sh-blue);transition:.18s}
.vcta:hover{transform:translateY(-2px)}
.vnote{color:var(--mut);font-size:13.5px;margin-top:12px}

.vherorow{display:flex;gap:16px;align-items:center;justify-content:center;
 flex-wrap:wrap;margin-top:24px}
.vherostat{color:var(--ink2);font-size:14.5px;font-weight:600}
.vherostat b{font-family:var(--disp);font-weight:800;color:var(--ink)}

/* ─── фильтры ───────────────────────────────────────────────────────────── */
.vfilters{position:sticky;top:0;z-index:20;background:rgba(255,255,255,.93);
 backdrop-filter:saturate(1.6) blur(12px);border-bottom:1px solid var(--line);
 padding:12px 0;margin-bottom:4px}
.vfrow{display:flex;gap:8px;align-items:center;overflow-x:auto;scrollbar-width:none}
.vfrow::-webkit-scrollbar{display:none}
.vpill{padding:8px 15px;border-radius:999px;border:1px solid var(--cbord);
 background:#fff;color:var(--ink2);font-size:13.5px;font-weight:700;
 white-space:nowrap;cursor:pointer;transition:.16s;flex-shrink:0}
.vpill:hover{color:var(--ink);border-color:rgba(37,99,235,.32)}
.vpill.on{background:#EAF1FF;color:var(--blue);border-color:rgba(37,99,235,.2)}
.vsep{width:1px;height:22px;background:var(--line);flex-shrink:0;margin:0 4px}
.vsrch{flex-shrink:0;margin-left:auto;position:relative}
.vsrch input{background:#fff;border:1px solid var(--cbord);border-radius:999px;
 padding:9px 16px 9px 38px;font-size:14px;width:196px;outline:0;transition:.18s;
 font-weight:600;font-family:var(--sans)}
.vsrch input:focus{border-color:var(--blue);width:236px;
 box-shadow:0 0 0 4px rgba(37,99,235,.12)}
.vsrch svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);
 color:var(--mut);pointer-events:none}

/* ─── панель сортировки и поиска ────────────────────────────────────────── */
.vbar{position:sticky;top:0;z-index:20;background:rgba(255,255,255,.94);
 backdrop-filter:saturate(1.6) blur(12px);border-bottom:1px solid var(--line);
 padding:11px 0}
.vbarin{display:flex;gap:12px;align-items:center}
.vsorts{display:flex;gap:4px;background:var(--soft);border-radius:12px;padding:4px;
 flex-shrink:0}
.vsort{padding:7px 14px;border-radius:9px;font-size:13.5px;font-weight:700;
 color:var(--ink2);white-space:nowrap;transition:.14s}
.vsort:hover{color:var(--ink)}
.vsort.on{background:#fff;color:var(--blue);box-shadow:0 1px 3px rgba(30,52,110,.12)}
.vsrch{position:relative;flex:1;max-width:320px}
.vsrch input{width:100%;background:#fff;border:1px solid var(--cbord);
 border-radius:11px;padding:9px 14px 9px 36px;font-size:14px;outline:0;
 transition:.16s;font-weight:600;font-family:var(--sans)}
.vsrch input:focus{border-color:var(--blue);box-shadow:0 0 0 4px rgba(37,99,235,.12)}
.vsrch svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);
 color:var(--mut);pointer-events:none}
.vfbtn{display:none;margin-left:auto;background:#fff;border:1px solid var(--cbord);
 border-radius:11px;padding:9px 16px;font-weight:700;font-size:14px;cursor:pointer;
 font-family:var(--sans);color:var(--ink)}

/* ─── две колонки: фильтры и список ─────────────────────────────────────── */
.vboard{padding:24px 0 70px}
.vcols{display:grid;grid-template-columns:236px 1fr;gap:28px;align-items:start}
.vside{position:sticky;top:74px}
.vfgroup{margin-bottom:22px}
.vfh{font-family:var(--disp);font-weight:700;font-size:13px;letter-spacing:.02em;
 text-transform:uppercase;color:var(--mut);margin-bottom:8px}
.vfac{display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:9px;
 font-size:14px;font-weight:600;color:var(--ink2);transition:.14s}
.vfac span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vfac i{font-style:normal;font-size:12px;font-weight:700;color:var(--mut);
 background:var(--soft);border-radius:999px;padding:1px 8px;flex-shrink:0}
.vfac:hover{background:var(--soft);color:var(--ink)}
.vfac.on{background:var(--chipbg);color:var(--blue)}
.vfac.on i{background:#fff;color:var(--blue)}
/* Пустые рубрики видно сразу и они не кликаются: иначе человек тыкает
   в фильтр и попадает в пустоту — самая частая беда маленьких каталогов. */
.vfac.off{opacity:.42;pointer-events:none}
.vfound{color:var(--mut);font-size:13.5px;font-weight:700;margin-bottom:14px}

/* ─── карточка ──────────────────────────────────────────────────────────── */
.vlist{display:grid;gap:18px;grid-template-columns:repeat(auto-fill,minmax(340px,1fr))}
.vcard{background:#fff;border:1px solid var(--cbord);border-radius:18px;
 overflow:hidden;display:flex;flex-direction:column;box-shadow:var(--sh1);
 transition:transform .18s,box-shadow .18s,border-color .18s}
/* Карточка прячется ТОЛЬКО когда точно есть кому её показать. Класс js ставит
   строчка в <head>; если скрипт не выполнился — правило не применится, и доска
   будет видна как есть. Иначе одна осечка в анимации делает раздел пустым:
   на проверке IntersectionObserver молча не сработал, и доска была пустой. */
html.js .vcard{opacity:0;transform:translateY(14px)}
html.js .vcard.vin{opacity:1;transform:none}
.vcard:hover{transform:translateY(-4px);box-shadow:var(--sh2);
 border-color:rgba(37,99,235,.22)}
.vshotwrap{display:block}
.vshot{aspect-ratio:16/9;background:var(--soft);position:relative;overflow:hidden;
 display:block;border-bottom:1px solid var(--line)}
.vshot img{width:100%;height:100%;object-fit:cover;transition:transform .5s}
.vcard:hover .vshot img{transform:scale(1.04)}
.vshot.vgen{display:flex;align-items:center;justify-content:center}
.vshot.vgen span{font-family:var(--disp);font-weight:800;font-size:56px;color:#fff;
 letter-spacing:-.03em;text-shadow:0 6px 22px rgba(0,0,0,.18)}

.vbody{padding:15px 17px 14px;display:flex;flex-direction:column;flex:1;gap:8px}
.vhead{display:flex;gap:11px;align-items:flex-start}
/* Логотип «наезжает» на превью: приём из всех витрин запусков — знак проекта
   привязывается к скриншоту и держит взгляд, а карточка перестаёт быть
   безымянной картинкой с подписью. */
.vlogo{width:48px;height:48px;border-radius:12px;flex-shrink:0;overflow:hidden;
 background:#fff;border:1px solid var(--cbord);box-shadow:var(--sh1);
 margin-top:-32px;display:block}
.vlogo img{width:100%;height:100%;object-fit:contain;background:#fff}
.vlogo.vgen{display:flex;align-items:center;justify-content:center;border:0;
 font-family:var(--disp);font-weight:800;font-size:21px;color:#fff}
.vnames{flex:1;min-width:0}
.vcard h3{font-family:var(--disp);font-weight:700;font-size:17px;
 letter-spacing:-.025em;line-height:1.25;color:var(--ink);margin:0}
.vcard h3 a:hover{color:var(--blue)}
.vrank{color:var(--mut);font-weight:800;margin-right:6px}
.vrank:before{content:"#"}
.vdom{color:var(--mut);font-size:12.5px;font-weight:600;margin-top:2px;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vtag1{color:var(--ink);font-size:14.5px;line-height:1.45;font-weight:600;margin:0}
.vprob{color:var(--ink2);font-size:13.5px;line-height:1.5;margin:0;
 display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.vaud{color:var(--ink2);font-size:13px;line-height:1.45;margin:0}
.vaud b{color:var(--mut);font-weight:700}
.vtags{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-top:2px}
.vtag{font-size:11px;font-weight:800;padding:3px 9px;border-radius:999px;
 background:var(--soft);color:var(--ink2)}
.vtag.vtool{background:var(--chipbg);color:var(--blue)}
.vtag.vfree{background:var(--goodbg);color:var(--good)}
.vtag.vwip{background:var(--warnbg);color:var(--warn)}
.vfoot{display:flex;align-items:center;gap:10px;border-top:1px solid var(--line);
 margin-top:auto;padding-top:11px}
.vwho{color:var(--mut);font-size:12.5px;font-weight:600;flex:1;min-width:0;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vopen{font-size:13px;font-weight:800;color:var(--blue)}

/* Лайк. Сердце, а не треугольник: «нравится» понятнее, чем «апвоут»,
   и не требует объяснения. */
.vvote{display:inline-flex;align-items:center;gap:6px;background:#fff;
 border:1px solid var(--cbord);border-radius:11px;padding:7px 11px;font-weight:800;
 font-size:13.5px;cursor:pointer;transition:.16s;flex-shrink:0;color:var(--ink2);
 font-family:var(--sans);align-self:flex-start}
.vvote:hover{border-color:#EF4444;color:#EF4444;background:#FDECEC}
.vvote.on{background:#FDECEC;border-color:rgba(239,68,68,.3);color:#EF4444}
.vvote svg{transition:transform .2s}
.vvote:hover svg{transform:scale(1.15)}
.vvote.vpop{animation:vpop .34s cubic-bezier(.3,1.4,.5,1)}
@keyframes vpop{40%{transform:scale(1.14)}100%{transform:scale(1)}}

.vmore{text-align:center;margin-top:28px}
.vempty{text-align:center;padding:60px 20px;color:var(--ink2);background:#fff;
 border:1px solid var(--cbord);border-radius:18px}
.vempty b{display:block;font-family:var(--disp);font-size:20px;color:var(--ink);
 margin-bottom:10px;letter-spacing:-.02em}
.vempty a{color:var(--blue);border-bottom:1px solid currentColor}

/* ─── чат сообщества ────────────────────────────────────────────────────── */
.vchat{display:flex;gap:13px;align-items:center;background:linear-gradient(135deg,
 #F2F6FF 0%,#EAF1FF 100%);border:1px solid rgba(37,99,235,.16);border-radius:16px;
 padding:16px;margin-top:20px}
.vchatico{width:40px;height:40px;border-radius:11px;background:var(--grad);color:#fff;
 display:flex;align-items:center;justify-content:center;flex-shrink:0;
 box-shadow:var(--sh-blue)}
.vchattx{flex:1;min-width:0}
.vchattx b{display:block;font-family:var(--disp);font-size:14.5px;letter-spacing:-.02em;
 color:var(--ink)}
.vchattx span{display:block;color:var(--ink2);font-size:13px;line-height:1.45;
 margin-top:3px}
.vchatbtn{flex-shrink:0;background:var(--grad);color:#fff;font-weight:800;font-size:13.5px;
 padding:10px 17px;border-radius:11px;box-shadow:var(--sh-blue);transition:.18s}
.vchatbtn:hover{transform:translateY(-2px)}
.vchat.vcompact{flex-wrap:wrap;gap:11px}
.vchat.vcompact .vchatbtn{width:100%;text-align:center}
.vdonechat{margin-top:26px;text-align:left}
@media(max-width:520px){
 .vchat{flex-wrap:wrap}
 .vchat .vchatbtn{width:100%;text-align:center}
}

/* ─── страница проекта ──────────────────────────────────────────────────── */
.vcrumb{padding:20px 0 0;color:var(--mut);font-size:13.5px;font-weight:600}
.vcrumb a:hover{color:var(--blue)}
.vph{padding:18px 0 30px;display:grid;grid-template-columns:1.05fr .95fr;gap:34px;
 align-items:start}
.vphead{display:flex;gap:15px;align-items:center}
.vphead .vlogo{width:56px;height:56px;margin-top:0;border-radius:14px}
.vphead .vlogo.vgen{font-size:25px}
.vph h1{font-family:var(--disp);font-weight:700;font-size:clamp(27px,4.2vw,42px);
 letter-spacing:-.03em;line-height:1.07;margin:0}
.vpdom{color:var(--mut);font-size:13.5px;font-weight:600;margin-top:3px}
.vpprob{color:var(--ink2);font-size:15.5px;line-height:1.5;margin-top:10px;
 padding-left:13px;border-left:3px solid var(--chipbg)}
.vpaud p{color:var(--ink);font-weight:600}
.vplead{color:var(--ink2);font-size:17px;margin-top:13px;line-height:1.55}
.vrow{display:flex;gap:10px;flex-wrap:wrap;margin-top:20px;align-items:center}
.vgo{display:inline-flex;align-items:center;gap:9px;background:var(--grad);color:#fff;
 font-weight:800;font-size:15.5px;padding:14px 26px;border-radius:14px;
 box-shadow:var(--sh-blue);transition:.18s;border:0;cursor:pointer;
 font-family:var(--sans)}
.vgo:hover{transform:translateY(-2px)}
.vshotbig{display:block;border-radius:18px;overflow:hidden;border:1px solid var(--cbord);
 background:var(--soft);aspect-ratio:16/10;box-shadow:var(--sh1)}
.vshotbig img{width:100%;height:100%;object-fit:cover}
.vshotbig.vgen{display:flex;align-items:center;justify-content:center}
.vshotbig.vgen span{font-family:var(--disp);font-weight:800;font-size:86px;color:#fff;
 letter-spacing:-.04em}

.vpanel{background:#fff;border:1px solid var(--cbord);border-radius:18px;padding:23px;
 margin-bottom:20px;box-shadow:var(--sh1)}
.vpanel h2{font-family:var(--disp);font-weight:700;font-size:18px;margin:0 0 12px;
 letter-spacing:-.025em}
.vpanel p{color:var(--ink2);line-height:1.65;font-weight:500;margin:0}
/* Описание пишет автор проекта — его переносы строк сохраняем. Свои абзацы
   вёрстки помечать этим классом нельзя: отступы исходника уедут лесенкой. */
.vpanel p.vpre{white-space:pre-wrap}
.vkv{display:grid;grid-template-columns:auto 1fr;gap:11px 20px;font-size:14.5px;margin:0}
.vkv dt{color:var(--mut);font-weight:600}
.vkv dd{color:var(--ink);font-weight:700;margin:0}
.vkv dd a{border-bottom:1px solid currentColor}
.vkv dd a:hover{color:var(--blue)}
.vsect{display:grid;grid-template-columns:1fr 320px;gap:22px;padding-bottom:60px}
.vnear{display:flex;gap:11px;align-items:center;padding:10px 0;
 border-bottom:1px solid var(--line)}
.vnear:last-child{border-bottom:0}
.vnear b{font-family:var(--disp);font-size:14.5px;flex:1;font-weight:700}
.vnear:hover b{color:var(--blue)}
.vnear span{color:var(--mut);font-size:13px;font-weight:700}
@media(max-width:900px){.vph{grid-template-columns:1fr;gap:20px}
 .vsect{grid-template-columns:1fr}}

/* ─── форма ─────────────────────────────────────────────────────────────── */
.vform{max-width:690px;margin:0 auto;padding:30px 0 80px}
.vform h1{font-family:var(--disp);font-weight:700;font-size:clamp(27px,4.4vw,40px);
 letter-spacing:-.03em;line-height:1.08;text-align:center;margin:0}
.vformsub{color:var(--ink2);text-align:center;margin:13px auto 30px;max-width:52ch;
 font-size:15.5px}
.vsteps{display:flex;gap:8px;justify-content:center;margin-bottom:24px}
.vsteps i{width:34px;height:4px;border-radius:2px;background:var(--line)}
.vsteps i.on{background:var(--grad)}
.vfld{margin-bottom:18px}
.vfld label{display:block;font-weight:800;font-size:14px;margin-bottom:7px}
.vfld .vhint{color:var(--mut);font-size:13px;font-weight:500;margin-top:5px;
 line-height:1.5}
.vfld input,.vfld textarea,.vfld select{width:100%;background:#fff;
 border:1px solid var(--cbord);border-radius:13px;padding:13px 15px;font-size:15.5px;
 outline:0;transition:.16s;font-weight:600;font-family:var(--sans);color:var(--ink)}
.vfld input:focus,.vfld textarea:focus,.vfld select:focus{border-color:var(--blue);
 box-shadow:0 0 0 4px rgba(37,99,235,.12)}
.vfld input::placeholder,.vfld textarea::placeholder{color:var(--faint);font-weight:500}
.vfld textarea{min-height:116px;resize:vertical;line-height:1.55}
.vfld select{appearance:none;cursor:pointer;
 background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2398A0AF' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
 background-repeat:no-repeat;background-position:right 15px center;padding-right:40px}
.vtwo{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:600px){.vtwo{grid-template-columns:1fr}}
.vchips{display:flex;gap:8px;flex-wrap:wrap}
.vchip{padding:9px 15px;border-radius:11px;border:1px solid var(--cbord);background:#fff;
 font-size:14px;font-weight:700;cursor:pointer;transition:.15s;user-select:none;
 color:var(--ink2);position:relative}
.vchip:hover{border-color:rgba(37,99,235,.32);color:var(--ink)}
.vchip.on{background:#EAF1FF;border-color:rgba(37,99,235,.28);color:var(--blue)}
.vchip input{position:absolute;opacity:0;pointer-events:none}
.vsbmt{width:100%;background:var(--grad);color:#fff;font-weight:800;font-size:16.5px;
 padding:16px;border-radius:14px;border:0;cursor:pointer;margin-top:8px;
 box-shadow:var(--sh-blue);transition:.18s;font-family:var(--sans)}
.vsbmt:hover{transform:translateY(-2px)}
.vsbmt:disabled{opacity:.6;cursor:wait;transform:none}
.vhp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}

.vmsg{border-radius:13px;padding:13px 16px;font-size:14.5px;margin-bottom:18px;
 font-weight:600}
.vmsg.vbad{background:var(--badbg);border:1px solid rgba(239,68,68,.28);color:#B42318}
.vmsg.vbad a{color:#B42318;border-bottom:1px solid currentColor}
.vprev{background:#fff;border:1px solid var(--cbord);border-radius:16px;padding:15px;
 display:flex;gap:14px;align-items:center;margin-bottom:20px;box-shadow:var(--sh1)}
.vprev img{width:104px;height:66px;object-fit:cover;border-radius:11px;flex-shrink:0}
.vprev .vgen{width:104px;height:66px;border-radius:11px;flex-shrink:0;display:flex;
 align-items:center;justify-content:center;font-family:var(--disp);font-weight:800;
 font-size:26px;color:#fff}
.vprev b{display:block;font-family:var(--disp);font-size:15.5px;margin-bottom:3px;
 letter-spacing:-.02em}
.vprev span{color:var(--ink2);font-size:13.5px;display:-webkit-box;-webkit-line-clamp:2;
 -webkit-box-orient:vertical;overflow:hidden}

/* ─── успех ─────────────────────────────────────────────────────────────── */
.vdone{max-width:610px;margin:0 auto;padding:52px 0 80px;text-align:center}
.vtick{width:76px;height:76px;border-radius:50%;background:var(--grad);
 display:flex;align-items:center;justify-content:center;margin:0 auto 22px;
 box-shadow:var(--sh-blue);animation:vpop .5s cubic-bezier(.3,1.5,.5,1)}
.vdone h1{font-family:var(--disp);font-weight:700;font-size:clamp(26px,4.4vw,36px);
 letter-spacing:-.03em;line-height:1.1;margin:0}
.vdone>p{color:var(--ink2);margin:13px auto 0;max-width:46ch}
.vkeep{background:var(--soft);border:1px solid var(--line);border-radius:16px;
 padding:17px;margin-top:24px;text-align:left}
.vkeep b{font-size:14px;display:block;margin-bottom:9px}
.vkeep code{display:block;background:#fff;border:1px solid var(--cbord);
 border-radius:9px;padding:11px 13px;font-size:12.5px;word-break:break-all;
 color:var(--blue);font-family:ui-monospace,Menlo,monospace}
.vbtns{display:flex;gap:11px;justify-content:center;margin-top:22px;flex-wrap:wrap}
.vbtn2{border:1px solid var(--cbord);background:#fff;border-radius:14px;padding:14px 24px;
 font-weight:800;font-size:15px;cursor:pointer;transition:.16s;box-shadow:var(--sh1);
 color:var(--ink);font-family:var(--sans);display:inline-flex;align-items:center}
.vbtn2:hover{transform:translateY(-2px);border-color:rgba(37,99,235,.28);color:var(--blue)}

/* Ниже 980 боковая колонка фильтров не помещается: две колонки давали
   229 пикселей горизонтального скролла. Панель прячется под кнопку. */
@media(max-width:980px){
 .vcols{grid-template-columns:1fr}
 .vfbtn{display:block}
 .vside{position:static;display:none;background:#fff;border:1px solid var(--cbord);
  border-radius:16px;padding:16px;box-shadow:var(--sh1);margin-bottom:18px}
 .vside.open{display:block}
 .vsidein{display:grid;grid-template-columns:1fr 1fr;gap:18px;align-items:start}
 .vsidein .vchat{grid-column:1/-1}
}
@media(max-width:760px){
 .vhero{padding:36px 0 20px}
 .vlist{grid-template-columns:1fr;gap:16px}
 .vbarin{flex-wrap:wrap}
 .vsorts{order:1}
 .vfbtn{order:2}
 .vsrch{order:3;max-width:none;flex-basis:100%}
 .vsidein{grid-template-columns:1fr}
}
@media(prefers-reduced-motion:reduce){
 .vcard,.vcta,.vgo,.vtick{animation:none!important;transition:none!important}
 html.js .vcard{opacity:1;transform:none}
}
