каталог всяких штучек, которые я сделал.

сайты, сервисы, инструменты и эксперименты. если хочется посмотреть их как презентацию, .

ничего не найдено

PRODUCT

id: vvrshn

Название: VVRSHN.ru

Категория: Сайт

Порядок списка: 1

Главная: да

NEW: нет

Статус: доступен

Ссылка: https://vvrshn.ru/

Кнопка: Открыть сайт

Коротко: Главный сайт и центральная точка всех моих проектов.

Класс визуала: site-main

DESCRIPTION

Мой основной сайт и центральная точка всего, чем я занимаюсь. Здесь собраны видеосъёмка, свадьбы, отдельные проекты для event-индустрии, мои эксперименты с разработкой, сервисы, расширения и другие штуки, которые постепенно появляются вокруг моей работы.

ENDDESCRIPTION

VISUAL_HTML

<div class="site-shell">

<div class="site-left">

<div class="site-name">

Я Вова<br>

Вершинин.

</div>

<div class="site-subtitle">

Это мой сайт.

</div>

<div class="site-lines">

<div class="site-line line-a"></div>

<div class="site-line line-b"></div>

<div class="site-line line-c"></div>

</div>

</div>

<div class="site-right">

<div class="site-browser">

<div class="browser-top">

<div class="browser-dots">

<span></span>

<span></span>

<span></span>

</div>

<div class="browser-url">

vvrshn.ru

</div>

</div>

<div class="browser-content">

<div class="browser-title">

Вова<br>

Вершинин

</div>

<div class="browser-links">

<div class="browser-link link-1">

свадьбы

</div>

<div class="browser-link link-2">

показываю видео

</div>

<div class="browser-link link-3">

разработки

</div>

<div class="browser-link link-4">

vibe coding

</div>

</div>

</div>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.site-main {

background:

linear-gradient(

115deg,

#f5f4ef 0%,

#fbfaf6 49.9%,

#0d0d0e 50%,

#080809 100%

);

}

.site-main .site-shell {

position: absolute;

inset: 0;

display: grid;

grid-template-columns:

1fr

1fr;

overflow: hidden;

}

/* =========================================================

LEFT

========================================================= */

.site-main .site-left {

position: relative;

display: flex;

flex-direction: column;

justify-content: center;

padding:

10%

11%;

}

.site-main .site-name {

color: #111;

font-size:

clamp(

19px,

3.3vw,

48px

);

line-height: .9;

font-weight: 760;

letter-spacing: -.075em;

}

.site-main .site-subtitle {

margin-top: 7%;

color:

rgba(0,0,0,.38);

font-size:

clamp(

6px,

.8vw,

11px

);

letter-spacing: -.02em;

}

.site-main .site-lines {

width: 58%;

margin-top: 12%;

display: flex;

flex-direction: column;

gap:

clamp(

4px,

.55vw,

8px

);

}

.site-main .site-line {

height:

clamp(

3px,

.42vw,

6px

);

border-radius: 999px;

background:

rgba(0,0,0,.08);

}

.site-main .line-a {

width: 100%;

}

.site-main .line-b {

width: 74%;

}

.site-main .line-c {

width: 46%;

}

/* =========================================================

RIGHT

========================================================= */

.site-main .site-right {

position: relative;

display: flex;

align-items: center;

justify-content: center;

}

.site-main .site-browser {

position: absolute;

left: 10%;

right: 7%;

top: 10%;

bottom: 10%;

overflow: hidden;

border:

1px solid

rgba(255,255,255,.09);

border-radius:

clamp(

15px,

2vw,

28px

);

background:

#151516;

box-shadow:

0

34px

90px

rgba(0,0,0,.42);

transform:

perspective(900px)

rotateY(-7deg)

rotateZ(1.2deg)

translateX(3%);

transition:

transform

.55s

cubic-bezier(.2,.8,.2,1);

}

.site-main:hover .site-browser {

transform:

perspective(900px)

rotateY(0deg)

rotateZ(0deg)

translateX(0);

}

/* =========================================================

BROWSER TOP

========================================================= */

.site-main .browser-top {

height: 14%;

min-height: 22px;

padding:

0

5%;

display: flex;

align-items: center;

border-bottom:

1px solid

rgba(255,255,255,.055);

background:

rgba(255,255,255,.025);

}

.site-main .browser-dots {

display: flex;

gap:

clamp(

3px,

.4vw,

5px

);

}

.site-main .browser-dots span {

width:

clamp(

3px,

.45vw,

6px

);

aspect-ratio: 1;

border-radius: 50%;

background:

rgba(255,255,255,.18);

}

.site-main .browser-url {

position: absolute;

left: 50%;

transform:

translateX(-50%);

color:

rgba(255,255,255,.24);

font-size:

clamp(

4px,

.55vw,

8px

);

letter-spacing: .02em;

}

/* =========================================================

BROWSER CONTENT

========================================================= */

.site-main .browser-content {

position: absolute;

inset:

14%

0

0;

padding:

12%;

display: flex;

flex-direction: column;

justify-content: center;

}

.site-main .browser-title {

color: #fff;

font-size:

clamp(

14px,

2.25vw,

32px

);

line-height: .92;

font-weight: 720;

letter-spacing: -.065em;

}

.site-main .browser-links {

margin-top: 13%;

display: flex;

flex-direction: column;

gap:

clamp(

5px,

.7vw,

9px

);

}

.site-main .browser-link {

width: fit-content;

position: relative;

color:

rgba(255,255,255,.42);

font-size:

clamp(

5px,

.65vw,

9px

);

line-height: 1;

transition:

color .35s ease,

transform .35s ease;

}

.site-main .browser-link::after {

content: "";

position: absolute;

left: 0;

bottom: -3px;

width: 0;

height: 1px;

background:

rgba(255,255,255,.8);

transition:

width .45s

cubic-bezier(.2,.8,.2,1);

}

.site-main:hover .link-1 {

color:

rgba(255,255,255,.86);

transform:

translateX(3px);

}

.site-main:hover .link-1::after {

width: 100%;

}

.site-main:hover .link-2 {

color:

rgba(255,255,255,.65);

transform:

translateX(6px);

}

.site-main:hover .link-3 {

color:

rgba(255,255,255,.55);

transform:

translateX(9px);

}

.site-main:hover .link-4 {

color:

rgba(255,255,255,.46);

transform:

translateX(12px);

}

/* =========================================================

LIGHT MOTION

========================================================= */

.site-main .site-browser::after {

content: "";

position: absolute;

width: 70%;

height: 150%;

left: -90%;

top: -25%;

transform:

rotate(18deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.035),

transparent

);

transition:

left

1s

cubic-bezier(.2,.8,.2,1);

pointer-events: none;

}

.site-main:hover .site-browser::after {

left: 130%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: vvrshn-watch

Название: VVRSHN Watch

Категория: Сайт

Порядок списка: 2

Главная: нет

NEW: нет

Статус: доступен

Ссылка: https://vvrshn.ru/watch

Кнопка: Открыть сайт

Коротко: Поиск и быстрый просмотр видео из моего портфолио.

Класс визуала: watch-site

DESCRIPTION

Отдельный сайт для просмотра моего видеопортфолио. Работы автоматически собираются в единую базу, а нужное видео можно найти через поиск и быстрые категории. Это способ не листать десятки страниц портфолио, а сразу находить подходящие примеры съёмок.

ENDDESCRIPTION

VISUAL_HTML

<div class="watch-window">

<div class="watch-top">

<div class="watch-logo">

watch

</div>

<div class="watch-counter">

портфолио

</div>

</div>

<div class="watch-search">

<span>

свадьба SDE репортаж

</span>

<div class="search-icon"></div>

</div>

<div class="watch-tags">

<div class="watch-tag active">

SDE

</div>

<div class="watch-tag">

свадьба

</div>

</div>

<div class="watch-grid">

<div class="watch-video video-1">

<div class="video-play"></div>

</div>

<div class="watch-video video-2">

<div class="video-play"></div>

</div>

<div class="watch-video video-3">

<div class="video-play"></div>

</div>

<div class="watch-video video-4">

<div class="video-play"></div>

</div>

</div>

<div class="watch-more">

показать ещё

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.watch-site {

background:

linear-gradient(

145deg,

#f5f5f2,

#e8e8e4

);

}

.watch-site .watch-window {

position: absolute;

left: 8%;

right: 8%;

top: 10%;

bottom: 10%;

padding: 5%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.06);

border-radius: 24px;

background:

rgba(255,255,255,.96);

box-shadow:

0

30px

80px

rgba(0,0,0,.10);

transform:

rotate(-1.2deg)

translateY(1%);

transition:

transform

.55s

cubic-bezier(.2,.8,.2,1);

}

.watch-site:hover .watch-window {

transform:

rotate(0)

translateY(0);

}

.watch-site .watch-top {

display: flex;

align-items: center;

justify-content: space-between;

}

.watch-site .watch-logo {

color: #111;

font-size:

clamp(

13px,

1.8vw,

25px

);

line-height: 1;

font-weight: 760;

letter-spacing: -.06em;

}

.watch-site .watch-counter {

color:

rgba(0,0,0,.30);

font-size:

clamp(

5px,

.55vw,

8px

);

text-transform: uppercase;

letter-spacing: .13em;

}

.watch-site .watch-search {

position: relative;

height: 14%;

margin-top: 6%;

padding:

0

4%;

display: flex;

align-items: center;

border:

1px solid

rgba(0,0,0,.08);

border-radius: 999px;

background: #f3f3f1;

color:

rgba(0,0,0,.27);

font-size:

clamp(

6px,

.75vw,

10px

);

}

.watch-site .search-icon {

position: absolute;

right: 4%;

width:

clamp(

8px,

1vw,

13px

);

aspect-ratio: 1;

border:

1.5px solid

rgba(0,0,0,.25);

border-radius: 50%;

}

.watch-site .search-icon::after {

content: "";

position: absolute;

right: -30%;

bottom: -20%;

width: 45%;

height: 1.5px;

transform:

rotate(45deg);

transform-origin:

center;

background:

rgba(0,0,0,.25);

}

.watch-site .watch-tags {

margin-top: 4%;

display: flex;

gap: 2%;

}

.watch-site .watch-tag {

padding:

2%

4%;

border-radius: 999px;

background: #f2f2ef;

color:

rgba(0,0,0,.42);

font-size:

clamp(

5px,

.55vw,

8px

);

}

.watch-site .watch-tag.active {

background: #111;

color: #fff;

}

.watch-site .watch-grid {

height: 43%;

margin-top: 5%;

display: grid;

grid-template-columns:

repeat(

2,

1fr

);

grid-template-rows:

repeat(

2,

1fr

);

gap: 5%;

}

.watch-site .watch-video {

position: relative;

overflow: hidden;

border-radius: 10px;

background: #d8d8d4;

}

.watch-site .video-1 {

background:

linear-gradient(

135deg,

#a99a8c,

#ece0d4 47%,

#726960

);

}

.watch-site .video-2 {

background:

linear-gradient(

145deg,

#66727b,

#bac4c9 46%,

#34383d

);

}

.watch-site .video-3 {

background:

linear-gradient(

145deg,

#c5b09b,

#7b6654 52%,

#e2d6c9

);

}

.watch-site .video-4 {

background:

linear-gradient(

145deg,

#807368,

#d0c8be 48%,

#4f4b48

);

}

.watch-site .watch-video::before {

content: "";

position: absolute;

inset: 0;

background:

linear-gradient(

180deg,

rgba(255,255,255,.10),

rgba(0,0,0,.14)

);

}

.watch-site .video-play {

position: absolute;

left: 50%;

top: 50%;

width:

clamp(

14px,

2.2vw,

28px

);

aspect-ratio: 1;

transform:

translate(

-50%,

-50%

);

border-radius: 50%;

background:

rgba(255,255,255,.88);

box-shadow:

0

5px

20px

rgba(0,0,0,.12);

}

.watch-site .video-play::after {

content: "";

position: absolute;

left: 54%;

top: 50%;

transform:

translate(

-50%,

-50%

);

width: 0;

height: 0;

border-top:

3px solid

transparent;

border-bottom:

3px solid

transparent;

border-left:

5px solid

#111;

}

.watch-site .watch-more {

width: fit-content;

margin:

5%

auto

0;

color:

rgba(0,0,0,.32);

font-size:

clamp(

5px,

.55vw,

8px

);

letter-spacing: .02em;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: wfolio-tools

Название: Wfolio Tools

Категория: Расширение

Порядок списка: 1

Главная: нет

NEW: нет

Статус: личный инструмент

Коротко: Расширение, которое добавляет в Wfolio папки для страниц и нормальный редактор HTML-кода.

Класс визуала: wfolio-tools

DESCRIPTION

Моё браузерное расширение для Wfolio. Оно добавляет функции, которых мне не хватало в обычной работе с конструктором: позволяет организовывать страницы по папкам и делает редактирование больших HTML-блоков заметно удобнее. Проект появился из постоянной работы с собственными сайтами на Wfolio и постепенно превращается в набор улучшений самого рабочего интерфейса.

ENDDESCRIPTION

VISUAL_HTML

<div class="wf-window">

<div class="wf-sidebar">

<div class="wf-brand">

wfolio

</div>

<div class="wf-section-title">

СТРАНИЦЫ

</div>

<div class="wf-folder folder-open">

<div class="folder-row">

<span class="folder-icon"></span>

<span>Сайты</span>

<span class="folder-arrow"></span>

</div>

<div class="folder-pages">

<div class="wf-page active">

Главная

</div>

<div class="wf-page">

Каталог

</div>

<div class="wf-page">

Watch

</div>

</div>

</div>

<div class="wf-folder">

<div class="folder-row">

<span class="folder-icon"></span>

<span>Проекты</span>

<span class="folder-arrow"></span>

</div>

</div>

<div class="wf-folder">

<div class="folder-row">

<span class="folder-icon"></span>

<span>Архив</span>

<span class="folder-arrow"></span>

</div>

</div>

</div>

<div class="wf-editor">

<div class="editor-top">

<div class="editor-title">

HTML

</div>

<div class="editor-badge">

Wfolio Tools

</div>

</div>

<div class="editor-code">

<div class="code-line">

<span class="num">01</span>

<span class="pink">&lt;div</span>

<span class="blue"> class</span>

<span class="white">=</span>

<span class="green">"site"</span>

<span class="pink">&gt;</span>

</div>

<div class="code-line indent">

<span class="num">02</span>

<span class="pink">&lt;h1&gt;</span>

<span class="white">Вова Вершинин</span>

<span class="pink">&lt;/h1&gt;</span>

</div>

<div class="code-line indent">

<span class="num">03</span>

<span class="pink">&lt;p&gt;</span>

<span class="white">Это мой сайт.</span>

<span class="pink">&lt;/p&gt;</span>

</div>

<div class="code-line">

<span class="num">04</span>

<span class="pink">&lt;/div&gt;</span>

</div>

<div class="code-line empty">

<span class="num">05</span>

</div>

<div class="code-line">

<span class="num">06</span>

<span class="purple">.site</span>

<span class="white"> {</span>

</div>

<div class="code-line indent">

<span class="num">07</span>

<span class="blue">display</span>

<span class="white">:</span>

<span class="green"> grid</span>

<span class="white">;</span>

</div>

<div class="code-line indent">

<span class="num">08</span>

<span class="blue">min-height</span>

<span class="white">:</span>

<span class="orange"> 100vh</span>

<span class="white">;</span>

</div>

<div class="code-line">

<span class="num">09</span>

<span class="white">}</span>

<span class="cursor"></span>

</div>

</div>

<div class="editor-status">

<div>

HTML / CSS

</div>

<div>

9 строк

</div>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.wfolio-tools {

background:

linear-gradient(

145deg,

#e9e9e7,

#f5f5f2

);

}

/* =========================================================

WINDOW

========================================================= */

.wfolio-tools .wf-window {

position: absolute;

left: 7%;

right: 7%;

top: 9%;

bottom: 9%;

display: grid;

grid-template-columns:

34%

66%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

15px,

2vw,

27px

);

background: #fff;

box-shadow:

0

30px

85px

rgba(0,0,0,.14);

transform:

perspective(1000px)

rotateX(1deg)

rotateY(-2deg)

translateY(1%);

transition:

transform

.55s

cubic-bezier(.2,.8,.2,1),

box-shadow

.55s

cubic-bezier(.2,.8,.2,1);

}

.wfolio-tools:hover .wf-window {

transform:

perspective(1000px)

rotateX(0deg)

rotateY(0deg)

translateY(0);

box-shadow:

0

38px

100px

rgba(0,0,0,.18);

}

/* =========================================================

SIDEBAR

========================================================= */

.wfolio-tools .wf-sidebar {

position: relative;

padding:

8%

8%;

overflow: hidden;

border-right:

1px solid

rgba(0,0,0,.07);

background:

#f4f4f2;

}

.wfolio-tools .wf-brand {

color: #111;

font-size:

clamp(

10px,

1.3vw,

18px

);

font-weight: 750;

letter-spacing: -.05em;

}

.wfolio-tools .wf-section-title {

margin-top: 14%;

margin-bottom: 7%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.48vw,

7px

);

font-weight: 650;

letter-spacing: .13em;

}

/* =========================================================

FOLDERS

========================================================= */

.wfolio-tools .wf-folder {

margin-bottom:

clamp(

6px,

.8vw,

11px

);

}

.wfolio-tools .folder-row {

min-height:

clamp(

17px,

2.4vw,

30px

);

display: flex;

align-items: center;

gap: 7%;

color:

rgba(0,0,0,.58);

font-size:

clamp(

5px,

.65vw,

9px

);

font-weight: 560;

}

.wfolio-tools .folder-icon {

position: relative;

width:

clamp(

9px,

1.15vw,

15px

);

height:

clamp(

7px,

.82vw,

11px

);

border-radius:

2px;

background:

#d5d5d0;

}

.wfolio-tools .folder-icon::before {

content: "";

position: absolute;

left: 8%;

top: -25%;

width: 48%;

height: 38%;

border-radius:

2px

2px

0

0;

background:

#d5d5d0;

}

.wfolio-tools .folder-open

.folder-icon {

background: #111;

}

.wfolio-tools .folder-open

.folder-icon::before {

background: #111;

}

.wfolio-tools .folder-arrow {

width: 4px;

height: 4px;

margin-left: auto;

border-right:

1px solid

rgba(0,0,0,.25);

border-bottom:

1px solid

rgba(0,0,0,.25);

transform:

rotate(-45deg);

}

.wfolio-tools .folder-open

.folder-arrow {

transform:

rotate(45deg)

translateY(-1px);

}

/* =========================================================

PAGES

========================================================= */

.wfolio-tools .folder-pages {

margin:

1%

0

5%

15%;

padding-left: 8%;

border-left:

1px solid

rgba(0,0,0,.08);

}

.wfolio-tools .wf-page {

position: relative;

padding:

4%

7%;

border-radius: 6px;

color:

rgba(0,0,0,.35);

font-size:

clamp(

4px,

.56vw,

8px

);

transition:

background .35s ease,

color .35s ease,

transform .35s ease;

}

.wfolio-tools .wf-page.active {

background: #fff;

color: #111;

box-shadow:

0

5px

14px

rgba(0,0,0,.05);

}

.wfolio-tools:hover

.wf-page.active {

transform:

translateX(3px);

}

/* =========================================================

EDITOR

========================================================= */

.wfolio-tools .wf-editor {

position: relative;

overflow: hidden;

background:

#151518;

}

.wfolio-tools .editor-top {

height: 16%;

min-height: 25px;

padding:

0

6%;

display: flex;

align-items: center;

justify-content: space-between;

border-bottom:

1px solid

rgba(255,255,255,.06);

}

.wfolio-tools .editor-title {

color:

rgba(255,255,255,.86);

font-size:

clamp(

5px,

.7vw,

10px

);

font-weight: 580;

}

.wfolio-tools .editor-badge {

padding:

2%

4%;

border:

1px solid

rgba(255,255,255,.08);

border-radius: 999px;

background:

rgba(255,255,255,.05);

color:

rgba(255,255,255,.4);

font-size:

clamp(

4px,

.45vw,

7px

);

}

/* =========================================================

CODE

========================================================= */

.wfolio-tools .editor-code {

position: absolute;

left: 0;

right: 0;

top: 16%;

bottom: 12%;

padding:

7%

7%;

overflow: hidden;

font-family:

"SFMono-Regular",

Consolas,

"Liberation Mono",

monospace;

}

.wfolio-tools .code-line {

min-height:

clamp(

9px,

1.1vw,

15px

);

display: flex;

align-items: center;

white-space: nowrap;

color:

rgba(255,255,255,.74);

font-size:

clamp(

4px,

.53vw,

7.5px

);

line-height: 1.5;

}

.wfolio-tools .code-line.indent {

padding-left: 5%;

}

.wfolio-tools .num {

width: 12%;

flex: 0 0 auto;

color:

rgba(255,255,255,.16);

user-select: none;

}

.wfolio-tools .pink {

color: #ff7ab2;

}

.wfolio-tools .blue {

color: #7dcfff;

}

.wfolio-tools .green {

color: #b9e77c;

}

.wfolio-tools .orange {

color: #ffb86b;

}

.wfolio-tools .purple {

color: #bf9df7;

}

.wfolio-tools .white {

color:

rgba(255,255,255,.75);

}

/* =========================================================

CURSOR

========================================================= */

.wfolio-tools .cursor {

width: 1px;

height:

clamp(

6px,

.8vw,

10px

);

margin-left: 2px;

background:

rgba(255,255,255,.85);

animation:

wfCursor

1s

steps(1)

infinite;

}

@keyframes wfCursor {

0%,

48% {

opacity: 1;

}

49%,

100% {

opacity: 0;

}

}

/* =========================================================

STATUS BAR

========================================================= */

.wfolio-tools .editor-status {

position: absolute;

left: 0;

right: 0;

bottom: 0;

height: 12%;

min-height: 18px;

padding:

0

6%;

display: flex;

align-items: center;

justify-content: space-between;

border-top:

1px solid

rgba(255,255,255,.055);

background:

rgba(255,255,255,.025);

color:

rgba(255,255,255,.25);

font-size:

clamp(

4px,

.44vw,

6.5px

);

}

/* =========================================================

SUBTLE ANIMATION

========================================================= */

.wfolio-tools .editor-code::after {

content: "";

position: absolute;

left: 0;

top: 0;

width: 100%;

height: 1px;

background:

linear-gradient(

90deg,

transparent,

rgba(125,207,255,.25),

transparent

);

opacity: 0;

transform:

translateY(0);

transition:

opacity .3s ease;

}

.wfolio-tools:hover

.editor-code::after {

opacity: 1;

animation:

wfScan

2.4s

ease-in-out

infinite;

}

@keyframes wfScan {

0% {

transform:

translateY(5px);

}

100% {

transform:

translateY(145px);

}

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: wedding

Название: Свадебная видеосъёмка

Категория: Сайт

Порядок списка: 3

Главная: нет

NEW: нет

Статус: доступен

Ссылка: https://vvrshn.ru/wedding

Кнопка: Открыть сайт

Коротко: Сайт о свадебной видеосъёмке с интерактивным расчётом стоимости.

Класс визуала: wedding-calc

DESCRIPTION

Отдельный сайт о моей свадебной видеосъёмке. Здесь можно посмотреть, как я снимаю свадьбы, разобраться в формате работы, посмотреть примеры и самостоятельно рассчитать стоимость съёмки. Калькулятор учитывает параметры заказа и сразу показывает ориентировочную цену без необходимости сначала писать мне.

ENDDESCRIPTION

VISUAL_HTML

<div class="wedding-scene">

<div class="wedding-photo">

<div class="photo-sky"></div>

<div class="photo-ground"></div>

<div class="couple">

<div class="person groom">

<div class="head"></div>

<div class="body"></div>

</div>

<div class="person bride">

<div class="veil"></div>

<div class="head"></div>

<div class="body"></div>

</div>

</div>

<div class="wedding-copy">

<div class="wedding-label">

WEDDING FILMS

</div>

<div class="wedding-title">

Снимаю<br>

свадьбы.

</div>

<div class="wedding-small">

целый день без часов

</div>

</div>

</div>

<div class="calculator">

<div class="calc-top">

<div class="calc-title">

Рассчитать съёмку

</div>

<div class="calc-step">

03 / 04

</div>

</div>

<div class="calc-question">

Сколько часов снимаем?

</div>

<div class="hours-row">

<div class="hour">

6

</div>

<div class="hour">

8

</div>

<div class="hour active">

10

</div>

<div class="hour">

12

</div>

</div>

<div class="calc-options">

<div class="calc-option active">

<span class="check"></span>

клип

</div>

<div class="calc-option active">

<span class="check"></span>

фильм

</div>

</div>

<div class="calc-divider"></div>

<div class="calc-result">

<div>

<div class="result-label">

стоимость

</div>

<div class="result-price">

190 000 ₽

</div>

</div>

<div class="calc-arrow">

</div>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.wedding-calc {

background:

linear-gradient(

135deg,

#e9e3dc,

#f7f4ef

);

}

/* =========================================================

SCENE

========================================================= */

.wedding-calc .wedding-scene {

position: absolute;

inset: 7%;

display: grid;

grid-template-columns:

54%

46%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.06);

border-radius:

clamp(

16px,

2vw,

28px

);

background: #fff;

box-shadow:

0

30px

85px

rgba(0,0,0,.13);

transform:

perspective(1100px)

rotateX(.8deg)

rotateY(-1.5deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.wedding-calc:hover .wedding-scene {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

38px

100px

rgba(0,0,0,.17);

}

/* =========================================================

WEDDING VISUAL

========================================================= */

.wedding-calc .wedding-photo {

position: relative;

overflow: hidden;

background:

#cbc3b9;

}

.wedding-calc .photo-sky {

position: absolute;

inset:

0

0

42%;

background:

linear-gradient(

180deg,

#d9d6d1,

#c5c0b9

);

}

.wedding-calc .photo-ground {

position: absolute;

left: -10%;

right: -10%;

bottom: -8%;

height: 57%;

border-radius:

50%

50%

0

0;

background:

linear-gradient(

180deg,

#847d73,

#5d5851

);

}

.wedding-calc .photo-ground::after {

content: "";

position: absolute;

inset: 0;

background:

repeating-linear-gradient(

112deg,

transparent

0

9px,

rgba(255,255,255,.025)

10px

11px

);

}

/* =========================================================

COUPLE

========================================================= */

.wedding-calc .couple {

position: absolute;

z-index: 5;

left: 55%;

bottom: 12%;

width: 27%;

height: 52%;

transform:

translateX(-50%);

}

.wedding-calc .person {

position: absolute;

bottom: 0;

width: 46%;

height: 100%;

}

.wedding-calc .groom {

left: 8%;

}

.wedding-calc .bride {

right: 5%;

}

.wedding-calc .person .head {

position: absolute;

left: 50%;

top: 7%;

width: 42%;

aspect-ratio: 1;

transform:

translateX(-50%);

border-radius:

50%;

background:

#c9a88f;

}

.wedding-calc .groom .body {

position: absolute;

left: 18%;

right: 18%;

top: 28%;

bottom: 0;

border-radius:

40%

40%

8%

8%;

background:

#292929;

}

.wedding-calc .bride .body {

position: absolute;

left: 4%;

right: 4%;

top: 27%;

bottom: 0;

clip-path:

polygon(

35% 0,

65% 0,

100% 100%,

0 100%

);

background:

linear-gradient(

180deg,

#f9f8f3,

#e8e5df

);

}

.wedding-calc .veil {

position: absolute;

z-index: -1;

left: -30%;

top: 14%;

width: 105%;

height: 72%;

border-radius:

60%

10%

50%

35%;

background:

linear-gradient(

130deg,

rgba(255,255,255,.72),

rgba(255,255,255,.10)

);

transform:

rotate(10deg);

transform-origin:

top right;

transition:

transform

1s

cubic-bezier(.2,.8,.2,1);

}

.wedding-calc:hover .veil {

transform:

rotate(15deg)

translateX(-4%);

}

/* =========================================================

WEDDING COPY

========================================================= */

.wedding-calc .wedding-copy {

position: absolute;

z-index: 10;

left: 9%;

top: 12%;

}

.wedding-calc .wedding-label {

margin-bottom: 10%;

color:

rgba(0,0,0,.36);

font-size:

clamp(

4px,

.5vw,

7px

);

font-weight: 650;

letter-spacing: .15em;

}

.wedding-calc .wedding-title {

color: #111;

font-size:

clamp(

16px,

2.6vw,

37px

);

line-height: .92;

font-weight: 720;

letter-spacing: -.065em;

}

.wedding-calc .wedding-small {

margin-top: 10%;

color:

rgba(0,0,0,.43);

font-size:

clamp(

5px,

.65vw,

9px

);

}

/* =========================================================

CALCULATOR

========================================================= */

.wedding-calc .calculator {

position: relative;

padding:

9%

10%;

background:

#fff;

}

.wedding-calc .calculator::before {

content: "";

position: absolute;

left: 0;

top: 8%;

bottom: 8%;

width: 1px;

background:

rgba(0,0,0,.06);

}

.wedding-calc .calc-top {

display: flex;

align-items: center;

justify-content: space-between;

}

.wedding-calc .calc-title {

color: #111;

font-size:

clamp(

7px,

.95vw,

13px

);

font-weight: 670;

letter-spacing: -.03em;

}

.wedding-calc .calc-step {

color:

rgba(0,0,0,.24);

font-size:

clamp(

4px,

.48vw,

7px

);

letter-spacing: .08em;

}

/* =========================================================

QUESTION

========================================================= */

.wedding-calc .calc-question {

margin-top: 15%;

color:

rgba(0,0,0,.48);

font-size:

clamp(

5px,

.65vw,

9px

);

}

/* =========================================================

HOURS

========================================================= */

.wedding-calc .hours-row {

margin-top: 7%;

display: grid;

grid-template-columns:

repeat(

4,

1fr

);

gap: 4%;

}

.wedding-calc .hour {

aspect-ratio:

1.25;

display: grid;

place-items: center;

border:

1px solid

rgba(0,0,0,.08);

border-radius:

clamp(

6px,

.7vw,

10px

);

background:

#f5f5f3;

color:

rgba(0,0,0,.42);

font-size:

clamp(

5px,

.68vw,

9px

);

transition:

transform .35s ease,

background .35s ease,

color .35s ease;

}

.wedding-calc .hour.active {

background: #111;

color: #fff;

}

.wedding-calc:hover

.hour.active {

transform:

translateY(-3px);

}

/* =========================================================

OPTIONS

========================================================= */

.wedding-calc .calc-options {

margin-top: 11%;

display: flex;

gap: 8%;

}

.wedding-calc .calc-option {

display: flex;

align-items: center;

gap:

clamp(

4px,

.5vw,

7px

);

color:

rgba(0,0,0,.35);

font-size:

clamp(

5px,

.57vw,

8px

);

}

.wedding-calc .calc-option.active {

color:

rgba(0,0,0,.70);

}

.wedding-calc .check {

position: relative;

width:

clamp(

8px,

.9vw,

12px

);

aspect-ratio: 1;

border-radius:

3px;

background: #111;

}

.wedding-calc .check::after {

content: "";

position: absolute;

left: 29%;

top: 16%;

width: 30%;

height: 50%;

border-right:

1px solid

#fff;

border-bottom:

1px solid

#fff;

transform:

rotate(42deg);

}

/* =========================================================

DIVIDER

========================================================= */

.wedding-calc .calc-divider {

height: 1px;

margin:

13%

0

9%;

background:

rgba(0,0,0,.07);

}

/* =========================================================

RESULT

========================================================= */

.wedding-calc .calc-result {

display: flex;

align-items: flex-end;

justify-content: space-between;

}

.wedding-calc .result-label {

margin-bottom: 7%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.48vw,

7px

);

text-transform: uppercase;

letter-spacing: .12em;

}

.wedding-calc .result-price {

color: #111;

font-size:

clamp(

11px,

1.7vw,

24px

);

line-height: 1;

font-weight: 720;

letter-spacing: -.055em;

}

.wedding-calc .calc-arrow {

width:

clamp(

20px,

2.7vw,

36px

);

aspect-ratio: 1;

display: grid;

place-items: center;

border-radius: 50%;

background: #111;

color: #fff;

font-size:

clamp(

8px,

1vw,

14px

);

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1);

}

.wedding-calc:hover

.calc-arrow {

transform:

translateX(4px)

rotate(-8deg);

}

/* =========================================================

LIGHT

========================================================= */

.wedding-calc .wedding-photo::after {

content: "";

position: absolute;

z-index: 20;

top: -60%;

left: -80%;

width: 45%;

height: 220%;

transform:

rotate(20deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.16),

transparent

);

transition:

left

1.2s

cubic-bezier(.2,.8,.2,1);

pointer-events: none;

}

.wedding-calc:hover

.wedding-photo::after {

left: 130%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: catalogue

Название: Каталог разработок

Категория: Сайт

Порядок списка: 4

Главная: нет

NEW: да

Статус: beta

Ссылка: https://vvrshn.ru/catalogue

Кнопка: Открыть каталог

Коротко: Каталог всех моих сайтов, сервисов, расширений и других цифровых штук.

Класс визуала: development-catalogue

DESCRIPTION

Этот самый каталог. Здесь в одном месте собраны сайты, сервисы, браузерные расширения и небольшие инструменты, которые я делаю. Каждый новый продукт добавляется отдельным блоком с описанием и собственным визуалом, а сам каталог автоматически собирает из них список и бесконечную карусель карточек.

ENDDESCRIPTION

VISUAL_HTML

<div class="catalogue-space">

<div class="catalogue-label">

VVRSHN / PRODUCTS

</div>

<div class="catalogue-cards">

<div class="mini-card card-left">

<div class="mini-visual visual-watch">

<div class="watch-search"></div>

<div class="watch-grid">

<span></span>

<span></span>

<span></span>

<span></span>

</div>

</div>

<div class="mini-info">

<div class="mini-type">

САЙТ

</div>

<div class="mini-title">

VVRSHN Watch

</div>

</div>

</div>

<div class="mini-card card-main">

<div class="mini-visual visual-catalogue">

<div class="visual-grid">

<span class="vg-1"></span>

<span class="vg-2"></span>

<span class="vg-3"></span>

<span class="vg-4"></span>

</div>

<div class="catalogue-new">

NEW

</div>

</div>

<div class="mini-info">

<div class="mini-type">

САЙТ

</div>

<div class="mini-title">

Каталог<br>

разработок

</div>

<div class="mini-line"></div>

<div class="mini-line short"></div>

</div>

</div>

<div class="mini-card card-right">

<div class="mini-visual visual-code">

<div class="code-bar"></div>

<div class="code-lines">

<span></span>

<span></span>

<span></span>

<span></span>

</div>

</div>

<div class="mini-info">

<div class="mini-type">

РАСШИРЕНИЕ

</div>

<div class="mini-title">

Wfolio Tools

</div>

</div>

</div>

</div>

<div class="catalogue-description">

<span class="description-title">

всё в одном месте

</span>

<span class="description-line line-one"></span>

<span class="description-line line-two"></span>

</div>

<div class="catalogue-list-button">

Показать списком

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.development-catalogue {

background:

radial-gradient(

circle at 50% 45%,

#29292b,

#111113 46%,

#050506 100%

);

}

/* =========================================================

SPACE

========================================================= */

.development-catalogue .catalogue-space {

position: absolute;

inset: 0;

overflow: hidden;

}

/* =========================================================

LABEL

========================================================= */

.development-catalogue .catalogue-label {

position: absolute;

z-index: 30;

left: 50%;

top: 8%;

transform:

translateX(-50%);

color:

rgba(255,255,255,.28);

font-size:

clamp(

4px,

.5vw,

7px

);

font-weight: 600;

letter-spacing: .14em;

white-space: nowrap;

}

/* =========================================================

CARDS WRAPPER

========================================================= */

.development-catalogue .catalogue-cards {

position: absolute;

inset: 0;

perspective: 900px;

transform-style:

preserve-3d;

}

/* =========================================================

MINI CARD

========================================================= */

.development-catalogue .mini-card {

position: absolute;

top: 47%;

left: 50%;

width: 34%;

height: 58%;

overflow: hidden;

display: grid;

grid-template-rows:

54%

46%;

border:

1px solid

rgba(255,255,255,.10);

border-radius:

clamp(

10px,

1.4vw,

19px

);

background: #fff;

box-shadow:

0

20px

55px

rgba(0,0,0,.38);

transform-style:

preserve-3d;

transition:

transform

.7s

cubic-bezier(.2,.8,.2,1),

filter

.7s

cubic-bezier(.2,.8,.2,1),

opacity

.7s

ease;

}

/* =========================================================

MAIN CARD

========================================================= */

.development-catalogue .card-main {

z-index: 10;

transform:

translate3d(

-50%,

-50%,

0

)

scale(1);

}

/* =========================================================

LEFT CARD

========================================================= */

.development-catalogue .card-left {

z-index: 5;

opacity: .48;

filter:

blur(4px)

brightness(.62);

transform:

translate3d(

-142%,

-50%,

-130px

)

rotateY(24deg)

scale(.78);

}

/* =========================================================

RIGHT CARD

========================================================= */

.development-catalogue .card-right {

z-index: 5;

opacity: .48;

filter:

blur(4px)

brightness(.62);

transform:

translate3d(

42%,

-50%,

-130px

)

rotateY(-24deg)

scale(.78);

}

/* =========================================================

HOVER

========================================================= */

.development-catalogue:hover

.card-main {

transform:

translate3d(

-50%,

-52%,

20px

)

scale(1.025);

}

.development-catalogue:hover

.card-left {

opacity: .61;

filter:

blur(3px)

brightness(.74);

transform:

translate3d(

-146%,

-50%,

-105px

)

rotateY(20deg)

scale(.80);

}

.development-catalogue:hover

.card-right {

opacity: .61;

filter:

blur(3px)

brightness(.74);

transform:

translate3d(

46%,

-50%,

-105px

)

rotateY(-20deg)

scale(.80);

}

/* =========================================================

VISUALS

========================================================= */

.development-catalogue .mini-visual {

position: relative;

overflow: hidden;

background: #eee;

}

.development-catalogue .visual-catalogue {

background:

linear-gradient(

145deg,

#202022,

#09090a

);

}

.development-catalogue .visual-watch {

padding: 12%;

background:

linear-gradient(

145deg,

#ececea,

#d8d8d4

);

}

.development-catalogue .visual-code {

padding: 12%;

background:

#18181b;

}

/* =========================================================

CENTRAL VISUAL

========================================================= */

.development-catalogue .visual-grid {

position: absolute;

left: 11%;

right: 11%;

top: 16%;

bottom: 16%;

display: grid;

grid-template-columns:

1fr

1fr;

gap: 7%;

}

.development-catalogue .visual-grid span {

position: relative;

overflow: hidden;

border-radius:

clamp(

4px,

.55vw,

8px

);

background:

rgba(255,255,255,.09);

}

.development-catalogue .visual-grid span::after {

content: "";

position: absolute;

left: 12%;

right: 12%;

bottom: 14%;

height: 8%;

border-radius: 999px;

background:

rgba(255,255,255,.18);

}

.development-catalogue .vg-1 {

background:

linear-gradient(

135deg,

#f0eee8 0 50%,

#151515 50%

) !important;

}

.development-catalogue .vg-2 {

background:

linear-gradient(

145deg,

#b7aea5,

#615b55

) !important;

}

.development-catalogue .vg-3 {

background:

linear-gradient(

145deg,

#25252b,

#4a4a53

) !important;

}

.development-catalogue .vg-4 {

background:

linear-gradient(

145deg,

#e5e5e2,

#adada8

) !important;

}

/* =========================================================

NEW

========================================================= */

.development-catalogue .catalogue-new {

position: absolute;

z-index: 20;

right: 8%;

top: 9%;

padding:

4%

6%;

border-radius: 999px;

background: #fff;

color: #111;

font-size:

clamp(

3px,

.4vw,

6px

);

font-weight: 750;

letter-spacing: .09em;

}

/* =========================================================

WATCH MINI VISUAL

========================================================= */

.development-catalogue .watch-search {

width: 100%;

height: 17%;

border-radius: 999px;

background:

rgba(255,255,255,.86);

box-shadow:

0

3px

10px

rgba(0,0,0,.04);

}

.development-catalogue .watch-grid {

height: 62%;

margin-top: 10%;

display: grid;

grid-template-columns:

1fr

1fr;

gap: 8%;

}

.development-catalogue .watch-grid span {

border-radius:

clamp(

3px,

.4vw,

6px

);

background:

linear-gradient(

145deg,

#9c9186,

#d0c7bd

);

}

/* =========================================================

CODE MINI VISUAL

========================================================= */

.development-catalogue .code-bar {

width: 46%;

height: 6%;

border-radius: 999px;

background:

rgba(255,255,255,.13);

}

.development-catalogue .code-lines {

margin-top: 14%;

display: flex;

flex-direction: column;

gap:

clamp(

3px,

.4vw,

5px

);

}

.development-catalogue .code-lines span {

height:

clamp(

2px,

.28vw,

4px

);

border-radius: 999px;

background:

rgba(255,255,255,.13);

}

.development-catalogue .code-lines span:nth-child(1) {

width: 82%;

}

.development-catalogue .code-lines span:nth-child(2) {

width: 61%;

background:

rgba(125,207,255,.32);

}

.development-catalogue .code-lines span:nth-child(3) {

width: 74%;

background:

rgba(185,231,124,.27);

}

.development-catalogue .code-lines span:nth-child(4) {

width: 43%;

}

/* =========================================================

INFO

========================================================= */

.development-catalogue .mini-info {

position: relative;

padding:

10%

11%;

background: #fff;

color: #111;

}

.development-catalogue .mini-type {

color:

rgba(0,0,0,.30);

font-size:

clamp(

3px,

.38vw,

5.5px

);

letter-spacing: .12em;

}

.development-catalogue .mini-title {

margin-top: 11%;

color: #111;

font-size:

clamp(

7px,

1.1vw,

16px

);

line-height: .95;

font-weight: 700;

letter-spacing: -.05em;

}

.development-catalogue .card-main

.mini-title {

font-size:

clamp(

9px,

1.45vw,

20px

);

}

/* =========================================================

LINES

========================================================= */

.development-catalogue .mini-line {

width: 74%;

height: 4px;

margin-top: 11%;

border-radius: 999px;

background:

rgba(0,0,0,.08);

}

.development-catalogue .mini-line.short {

width: 46%;

margin-top: 5%;

}

/* =========================================================

DESCRIPTION BELOW CARDS

========================================================= */

.development-catalogue .catalogue-description {

position: absolute;

left: 50%;

bottom: 8%;

width: 28%;

transform:

translateX(-50%);

display: flex;

flex-direction: column;

align-items: center;

gap:

clamp(

3px,

.4vw,

6px

);

opacity: .42;

}

.development-catalogue .description-title {

margin-bottom: 3%;

color: #fff;

font-size:

clamp(

4px,

.5vw,

7px

);

letter-spacing: .03em;

}

.development-catalogue .description-line {

height: 3px;

border-radius: 999px;

background:

rgba(255,255,255,.16);

}

.development-catalogue .line-one {

width: 100%;

}

.development-catalogue .line-two {

width: 68%;

}

/* =========================================================

LIST BUTTON

========================================================= */

.development-catalogue .catalogue-list-button {

position: absolute;

left: 50%;

bottom: 2.5%;

transform:

translateX(-50%);

padding:

1.5%

3%;

border:

1px solid

rgba(255,255,255,.12);

border-radius: 999px;

background:

rgba(255,255,255,.06);

color:

rgba(255,255,255,.46);

font-size:

clamp(

3px,

.4vw,

6px

);

white-space: nowrap;

}

/* =========================================================

SUBTLE LIGHT

========================================================= */

.development-catalogue .catalogue-space::after {

content: "";

position: absolute;

z-index: 50;

left: -40%;

top: -50%;

width: 30%;

height: 200%;

transform:

rotate(20deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.035),

transparent

);

transition:

left

1.25s

cubic-bezier(.2,.8,.2,1);

pointer-events: none;

}

.development-catalogue:hover

.catalogue-space::after {

left: 125%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: sufler

Название: Суфлёр

Категория: Сервис

Порядок списка: 1

Главная: нет

NEW: да

Статус: доступен

Ссылка: https://vvrshn.ru/sufler

Кнопка: Открыть суфлёр

Коротко: Бесплатный браузерный суфлёр для записи видео и работы с текстом.

Класс визуала: prompter

DESCRIPTION

Бесплатный браузерный суфлёр, который я сделал для собственных съёмок и записей клиентов. Текст можно быстро вставить, настроить размер, скорость и положение строки, запустить автоматическую прокрутку и читать прямо с экрана без установки отдельной программы. Сделал его потому, что многие существующие решения либо платные, либо неудобные.

ENDDESCRIPTION

VISUAL_HTML

<div class="prompter-stage">

<div class="prompter-screen">

<div class="prompter-text">

<div class="text-line muted">

Сегодня я хочу рассказать

</div>

<div class="text-line muted">

о новой штуке, которую

</div>

<div class="text-line active">

я сделал для своих съёмок.

</div>

<div class="text-line muted">

Она работает прямо

</div>

<div class="text-line muted">

в браузере.

</div>

</div>

<div class="focus-line">

<div class="focus-arrow">

</div>

</div>

<div class="prompter-gradient top"></div>

<div class="prompter-gradient bottom"></div>

</div>

<div class="prompter-controls">

<div class="control-row">

<div class="control-label">

СКОРОСТЬ

</div>

<div class="speed-control">

<div class="speed-track">

<div class="speed-fill"></div>

<div class="speed-knob"></div>

</div>

<div class="speed-value">

1.2×

</div>

</div>

</div>

<div class="control-row">

<div class="control-label">

ТЕКСТ

</div>

<div class="size-buttons">

<div class="size-button">

A

</div>

<div class="size-button active">

A

</div>

<div class="size-button large">

A

</div>

</div>

</div>

<div class="control-row">

<div class="control-label">

ОРИЕНТИР

</div>

<div class="position-control">

<div class="position-track">

<div class="position-point"></div>

</div>

</div>

</div>

<div class="prompter-actions">

<div class="secondary-action">

редактировать

</div>

<div class="start-action">

<span class="play-icon"></span>

Start

</div>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.prompter {

background:

linear-gradient(

145deg,

#e9e9e6,

#f6f6f3

);

}

/* =========================================================

STAGE

========================================================= */

.prompter .prompter-stage {

position: absolute;

inset: 7%;

display: grid;

grid-template-columns:

68%

32%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background: #fff;

box-shadow:

0

32px

90px

rgba(0,0,0,.13);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.5deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.prompter:hover .prompter-stage {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

40px

105px

rgba(0,0,0,.18);

}

/* =========================================================

SCREEN

========================================================= */

.prompter .prompter-screen {

position: relative;

overflow: hidden;

background:

radial-gradient(

circle at 50% 48%,

#1d1d20,

#09090a 72%

);

}

.prompter .prompter-text {

position: absolute;

left: 9%;

right: 9%;

top: 50%;

transform:

translateY(-50%);

display: flex;

flex-direction: column;

gap:

clamp(

7px,

1vw,

14px

);

transition:

transform

1.2s

cubic-bezier(.2,.8,.2,1);

}

.prompter:hover .prompter-text {

transform:

translateY(

calc(-50% - 13px)

);

}

/* =========================================================

TEXT

========================================================= */

.prompter .text-line {

text-align: center;

color: #fff;

font-size:

clamp(

9px,

1.45vw,

21px

);

line-height: 1.12;

font-weight: 620;

letter-spacing: -.035em;

white-space: nowrap;

}

.prompter .text-line.muted {

color:

rgba(255,255,255,.17);

filter:

blur(.15px);

}

.prompter .text-line.active {

color:

rgba(255,255,255,.96);

transform:

scale(1.025);

}

/* =========================================================

FOCUS

========================================================= */

.prompter .focus-line {

position: absolute;

z-index: 20;

left: 0;

right: 0;

top: 50%;

height: 1px;

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.13) 12%,

rgba(255,255,255,.13) 88%,

transparent

);

}

.prompter .focus-arrow {

position: absolute;

left:

clamp(

7px,

1vw,

14px

);

top: 50%;

transform:

translateY(-50%);

color:

rgba(255,255,255,.65);

font-size:

clamp(

10px,

1.5vw,

21px

);

font-weight: 300;

animation:

prompterArrow

1.7s

ease-in-out

infinite;

}

@keyframes prompterArrow {

0%,

100% {

opacity: .45;

transform:

translateY(-50%)

translateX(0);

}

50% {

opacity: 1;

transform:

translateY(-50%)

translateX(3px);

}

}

/* =========================================================

FADE

========================================================= */

.prompter .prompter-gradient {

position: absolute;

z-index: 10;

left: 0;

right: 0;

height: 25%;

pointer-events: none;

}

.prompter .prompter-gradient.top {

top: 0;

background:

linear-gradient(

180deg,

#09090a,

transparent

);

}

.prompter .prompter-gradient.bottom {

bottom: 0;

background:

linear-gradient(

0deg,

#09090a,

transparent

);

}

/* =========================================================

CONTROLS

========================================================= */

.prompter .prompter-controls {

position: relative;

padding:

12%

11%;

display: flex;

flex-direction: column;

background:

#f7f7f5;

}

.prompter .prompter-controls::before {

content: "";

position: absolute;

left: 0;

top: 8%;

bottom: 8%;

width: 1px;

background:

rgba(0,0,0,.07);

}

/* =========================================================

ROW

========================================================= */

.prompter .control-row {

padding:

10%

0;

border-bottom:

1px solid

rgba(0,0,0,.065);

}

.prompter .control-row:first-child {

padding-top: 3%;

}

.prompter .control-label {

margin-bottom: 9%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.45vw,

6.5px

);

font-weight: 650;

letter-spacing: .13em;

}

/* =========================================================

SPEED

========================================================= */

.prompter .speed-control {

display: flex;

align-items: center;

gap: 10%;

}

.prompter .speed-track {

position: relative;

width: 72%;

height: 3px;

border-radius: 999px;

background:

rgba(0,0,0,.09);

}

.prompter .speed-fill {

position: absolute;

left: 0;

top: 0;

bottom: 0;

width: 58%;

border-radius: inherit;

background: #111;

}

.prompter .speed-knob {

position: absolute;

left: 58%;

top: 50%;

width:

clamp(

7px,

.8vw,

11px

);

aspect-ratio: 1;

transform:

translate(

-50%,

-50%

);

border-radius: 50%;

background: #111;

box-shadow:

0

2px

8px

rgba(0,0,0,.18);

transition:

left

.7s

cubic-bezier(.2,.8,.2,1);

}

.prompter:hover .speed-knob {

left: 68%;

}

.prompter:hover .speed-fill {

width: 68%;

}

.prompter .speed-value {

color:

rgba(0,0,0,.48);

font-size:

clamp(

5px,

.58vw,

8px

);

white-space: nowrap;

}

/* =========================================================

FONT SIZE

========================================================= */

.prompter .size-buttons {

display: flex;

align-items: center;

gap: 7%;

}

.prompter .size-button {

width:

clamp(

20px,

2.4vw,

33px

);

aspect-ratio: 1;

display: grid;

place-items: center;

border:

1px solid

rgba(0,0,0,.08);

border-radius:

clamp(

5px,

.65vw,

9px

);

background: #fff;

color:

rgba(0,0,0,.35);

font-size:

clamp(

5px,

.6vw,

8px

);

}

.prompter .size-button.active {

background: #111;

color: #fff;

border-color: #111;

}

.prompter .size-button.large {

font-size:

clamp(

7px,

.85vw,

12px

);

}

/* =========================================================

POSITION

========================================================= */

.prompter .position-control {

padding:

4%

0;

}

.prompter .position-track {

position: relative;

width: 100%;

height: 3px;

border-radius: 999px;

background:

rgba(0,0,0,.09);

}

.prompter .position-point {

position: absolute;

left: 48%;

top: 50%;

width:

clamp(

7px,

.8vw,

11px

);

aspect-ratio: 1;

transform:

translate(

-50%,

-50%

);

border:

2px solid

#111;

border-radius: 50%;

background:

#f7f7f5;

}

/* =========================================================

ACTIONS

========================================================= */

.prompter .prompter-actions {

margin-top: auto;

display: flex;

align-items: center;

justify-content: space-between;

gap: 7%;

}

.prompter .secondary-action {

color:

rgba(0,0,0,.35);

font-size:

clamp(

4px,

.52vw,

7px

);

}

.prompter .start-action {

min-height:

clamp(

26px,

3.2vw,

43px

);

padding:

0

12%;

display: flex;

align-items: center;

justify-content: center;

gap:

clamp(

4px,

.5vw,

7px

);

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.6vw,

8px

);

font-weight: 620;

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1),

box-shadow

.4s

cubic-bezier(.2,.8,.2,1);

}

.prompter:hover .start-action {

transform:

translateY(-2px)

scale(1.025);

box-shadow:

0

8px

20px

rgba(0,0,0,.15);

}

/* =========================================================

PLAY

========================================================= */

.prompter .play-icon {

width: 0;

height: 0;

border-top:

3px solid

transparent;

border-bottom:

3px solid

transparent;

border-left:

5px solid

#fff;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: poster

Название: Постеронная

Категория: Сервис

Порядок списка: 2

Главная: нет

NEW: да

Статус: доступен

Ссылка: https://vvrshn.ru/poster

Кнопка: Открыть сервис

Коротко: Генератор вертикальных постеров и карточек для соцсетей прямо в браузере.

Класс визуала: poster-generator

DESCRIPTION

Браузерный генератор постеров и карточек для соцсетей. Можно собрать вертикальный макет, изменить текст, дату, время, подписи и акцентное слово, а затем сохранить готовую картинку. Я сделал его как быстрый инструмент для ситуаций, когда нужно оформить нормальный постер без отдельного графического редактора.

ENDDESCRIPTION

VISUAL_HTML

<div class="poster-workspace">

<div class="poster-toolbar">

<div class="tool-title">

Постеронная

</div>

<div class="tool-field">

<div class="field-label">

ЗАГОЛОВОК

</div>

<div class="field-box">

НОВАЯ ИСТОРИЯ

</div>

</div>

<div class="tool-field">

<div class="field-label">

АКЦЕНТНОЕ СЛОВО

</div>

<div class="field-box active">

ИСТОРИЯ

</div>

</div>

<div class="tool-row">

<div class="mini-field">

<div class="field-label">

ДАТА

</div>

<div class="field-box">

14.09

</div>

</div>

<div class="mini-field">

<div class="field-label">

ВРЕМЯ

</div>

<div class="field-box">

18:30

</div>

</div>

</div>

<div class="download-button">

Скачать

</div>

</div>

<div class="poster-preview-wrap">

<div class="poster-preview">

<div class="poster-word">

ИСТОРИЯ

</div>

<div class="poster-content">

<div class="poster-topline">

VOVA VERSHININ

</div>

<div class="poster-title">

НОВАЯ<br>

ИСТОРИЯ

</div>

<div class="poster-bottom">

<div class="poster-date">

14.09

</div>

<div class="poster-time">

18:30

</div>

</div>

</div>

</div>

<div class="preview-caption">

1080 × 1920

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.poster-generator {

background:

linear-gradient(

145deg,

#efefec,

#dadad6

);

}

/* =========================================================

WORKSPACE

========================================================= */

.poster-generator .poster-workspace {

position: absolute;

inset: 7%;

display: grid;

grid-template-columns:

38%

62%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background:

#f7f7f4;

box-shadow:

0

32px

90px

rgba(0,0,0,.14);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.5deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.poster-generator:hover

.poster-workspace {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

40px

105px

rgba(0,0,0,.18);

}

/* =========================================================

TOOLBAR

========================================================= */

.poster-generator .poster-toolbar {

position: relative;

padding:

11%

10%;

display: flex;

flex-direction: column;

border-right:

1px solid

rgba(0,0,0,.07);

background:

#f4f4f1;

}

.poster-generator .tool-title {

margin-bottom: 14%;

color: #111;

font-size:

clamp(

9px,

1.25vw,

18px

);

font-weight: 740;

letter-spacing: -.055em;

}

/* =========================================================

FIELDS

========================================================= */

.poster-generator .tool-field {

margin-bottom: 10%;

}

.poster-generator .tool-row {

display: grid;

grid-template-columns:

1fr

1fr;

gap: 7%;

}

.poster-generator .mini-field {

min-width: 0;

}

.poster-generator .field-label {

margin-bottom: 6%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.45vw,

6.5px

);

font-weight: 650;

letter-spacing: .13em;

}

.poster-generator .field-box {

min-height:

clamp(

23px,

3vw,

40px

);

padding:

0

8%;

display: flex;

align-items: center;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.08);

border-radius:

clamp(

5px,

.65vw,

9px

);

background: #fff;

color:

rgba(0,0,0,.48);

font-size:

clamp(

4px,

.53vw,

7.5px

);

white-space: nowrap;

}

.poster-generator .field-box.active {

border-color:

rgba(0,0,0,.18);

color: #111;

box-shadow:

0

4px

14px

rgba(0,0,0,.045);

}

/* =========================================================

DOWNLOAD

========================================================= */

.poster-generator .download-button {

min-height:

clamp(

28px,

3.4vw,

45px

);

margin-top: auto;

display: flex;

align-items: center;

justify-content: center;

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.6vw,

8px

);

font-weight: 620;

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1),

box-shadow

.4s

cubic-bezier(.2,.8,.2,1);

}

.poster-generator:hover

.download-button {

transform:

translateY(-2px);

box-shadow:

0

9px

24px

rgba(0,0,0,.15);

}

/* =========================================================

PREVIEW

========================================================= */

.poster-generator .poster-preview-wrap {

position: relative;

display: flex;

align-items: center;

justify-content: center;

background:

linear-gradient(

145deg,

#e1e1de,

#cfcfcb

);

}

/* =========================================================

POSTER

========================================================= */

.poster-generator .poster-preview {

position: relative;

height: 79%;

aspect-ratio:

9 / 16;

overflow: hidden;

border-radius:

clamp(

8px,

1vw,

14px

);

background:

linear-gradient(

160deg,

#171719,

#070708

);

box-shadow:

0

25px

60px

rgba(0,0,0,.25);

transform:

rotate(1.5deg)

translateY(-1%);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1);

}

.poster-generator:hover

.poster-preview {

transform:

rotate(0deg)

translateY(-2%);

}

/* =========================================================

BACKGROUND WORD

========================================================= */

.poster-generator .poster-word {

position: absolute;

left: 50%;

top: 48%;

transform:

translate(

-50%,

-50%

)

rotate(-90deg);

color:

rgba(255,255,255,.035);

font-size:

clamp(

28px,

5vw,

70px

);

line-height: .8;

font-weight: 800;

letter-spacing: -.07em;

white-space: nowrap;

}

/* =========================================================

POSTER CONTENT

========================================================= */

.poster-generator .poster-content {

position: absolute;

inset:

7%

9%;

display: flex;

flex-direction: column;

color: #fff;

}

.poster-generator .poster-topline {

color:

rgba(255,255,255,.38);

font-size:

clamp(

3px,

.38vw,

5.5px

);

letter-spacing: .17em;

}

/* =========================================================

TITLE

========================================================= */

.poster-generator .poster-title {

margin-top: auto;

margin-bottom: auto;

color: #fff;

font-size:

clamp(

13px,

2.2vw,

31px

);

line-height: .89;

font-weight: 730;

letter-spacing: -.07em;

}

/* =========================================================

BOTTOM

========================================================= */

.poster-generator .poster-bottom {

display: flex;

align-items: flex-end;

justify-content: space-between;

}

.poster-generator .poster-date {

color: #fff;

font-size:

clamp(

7px,

1vw,

14px

);

font-weight: 650;

letter-spacing: -.04em;

}

.poster-generator .poster-time {

color:

rgba(255,255,255,.44);

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

CAPTION

========================================================= */

.poster-generator .preview-caption {

position: absolute;

left: 50%;

bottom: 4%;

transform:

translateX(-50%);

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.43vw,

6px

);

letter-spacing: .07em;

}

/* =========================================================

LIGHT SWEEP

========================================================= */

.poster-generator .poster-preview::after {

content: "";

position: absolute;

top: -40%;

left: -90%;

width: 42%;

height: 180%;

transform:

rotate(18deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.055),

transparent

);

transition:

left

1.1s

cubic-bezier(.2,.8,.2,1);

pointer-events: none;

}

.poster-generator:hover

.poster-preview::after {

left: 130%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: media-converter

Название: Медиаконвертер

Категория: Сервис

Порядок списка: 3

Главная: нет

NEW: да

Статус: готов

Коротко: Конвертация видео и аудио прямо в браузере без загрузки файлов на сервер.

Класс визуала: media-converter

DESCRIPTION

Браузерный конвертер видео и аудио. Файл обрабатывается прямо на устройстве пользователя, без отправки исходника на сторонний сервер. Можно быстро изменить формат медиа и сохранить готовый файл обратно на компьютер или телефон. Сделал его как простой локальный инструмент без регистрации, облака и лишних действий.

ENDDESCRIPTION

VISUAL_HTML

<div class="converter-window">

<div class="converter-top">

<div class="converter-brand">

converter

</div>

<div class="converter-state">

LOCAL

</div>

</div>

<div class="converter-body">

<div class="source-file">

<div class="file-icon">

<div class="file-corner"></div>

<div class="file-play"></div>

</div>

<div class="file-info">

<div class="file-name">

wedding-film.mov

</div>

<div class="file-meta">

4K · 1.84 GB

</div>

</div>

</div>

<div class="conversion-flow">

<div class="flow-line"></div>

<div class="flow-arrow">

</div>

</div>

<div class="format-card">

<div class="format-label">

FORMAT

</div>

<div class="format-name">

MP4

</div>

<div class="format-codec">

H.264

</div>

</div>

</div>

<div class="converter-progress">

<div class="progress-head">

<span>

Конвертация

</span>

<span>

72%

</span>

</div>

<div class="progress-track">

<div class="progress-fill"></div>

</div>

</div>

<div class="converter-bottom">

<div class="privacy-note">

<span class="privacy-dot"></span>

файл остаётся на устройстве

</div>

<div class="save-button">

Скачать

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.media-converter {

background:

linear-gradient(

145deg,

#ececea,

#d9d9d5

);

}

/* =========================================================

WINDOW

========================================================= */

.media-converter .converter-window {

position: absolute;

left: 7%;

right: 7%;

top: 9%;

bottom: 9%;

padding:

5%

6%;

display: flex;

flex-direction: column;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background: #fbfbf9;

box-shadow:

0

32px

90px

rgba(0,0,0,.13);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.5deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.media-converter:hover

.converter-window {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

40px

105px

rgba(0,0,0,.17);

}

/* =========================================================

TOP

========================================================= */

.media-converter .converter-top {

display: flex;

align-items: center;

justify-content: space-between;

}

.media-converter .converter-brand {

color: #111;

font-size:

clamp(

10px,

1.4vw,

20px

);

font-weight: 760;

letter-spacing: -.055em;

}

.media-converter .converter-state {

padding:

1.5%

3%;

border:

1px solid

rgba(0,0,0,.08);

border-radius: 999px;

color:

rgba(0,0,0,.35);

font-size:

clamp(

3px,

.43vw,

6px

);

font-weight: 700;

letter-spacing: .14em;

}

/* =========================================================

BODY

========================================================= */

.media-converter .converter-body {

margin-top: auto;

margin-bottom: auto;

display: grid;

grid-template-columns:

1fr

18%

.72fr;

align-items: center;

gap: 3%;

}

/* =========================================================

SOURCE FILE

========================================================= */

.media-converter .source-file {

min-height:

clamp(

75px,

10vw,

135px

);

padding:

8%;

display: flex;

align-items: center;

gap: 9%;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

10px,

1.4vw,

18px

);

background: #fff;

box-shadow:

0

12px

30px

rgba(0,0,0,.05);

}

/* =========================================================

FILE ICON

========================================================= */

.media-converter .file-icon {

position: relative;

width:

clamp(

32px,

4.5vw,

62px

);

aspect-ratio:

.82;

flex: 0 0 auto;

overflow: hidden;

border-radius:

clamp(

6px,

.8vw,

11px

);

background:

linear-gradient(

145deg,

#27272b,

#0c0c0e

);

}

.media-converter .file-corner {

position: absolute;

right: 0;

top: 0;

width: 27%;

height: 23%;

background:

rgba(255,255,255,.11);

clip-path:

polygon(

0 0,

100% 100%,

100% 0

);

}

.media-converter .file-play {

position: absolute;

left: 50%;

top: 52%;

transform:

translate(

-50%,

-50%

);

width: 0;

height: 0;

border-top:

5px solid

transparent;

border-bottom:

5px solid

transparent;

border-left:

8px solid

rgba(255,255,255,.84);

}

/* =========================================================

FILE INFO

========================================================= */

.media-converter .file-info {

min-width: 0;

}

.media-converter .file-name {

overflow: hidden;

color: #111;

font-size:

clamp(

6px,

.82vw,

11px

);

font-weight: 620;

letter-spacing: -.025em;

text-overflow: ellipsis;

white-space: nowrap;

}

.media-converter .file-meta {

margin-top: 12%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

FLOW

========================================================= */

.media-converter .conversion-flow {

position: relative;

height: 50px;

}

.media-converter .flow-line {

position: absolute;

left: 0;

right: 0;

top: 50%;

height: 1px;

background:

linear-gradient(

90deg,

rgba(0,0,0,.05),

rgba(0,0,0,.19),

rgba(0,0,0,.05)

);

}

.media-converter .flow-arrow {

position: absolute;

left: 50%;

top: 50%;

width:

clamp(

22px,

2.8vw,

38px

);

aspect-ratio: 1;

display: grid;

place-items: center;

transform:

translate(

-50%,

-50%

);

border:

1px solid

rgba(0,0,0,.08);

border-radius: 50%;

background: #fbfbf9;

color:

rgba(0,0,0,.55);

font-size:

clamp(

8px,

1vw,

14px

);

transition:

transform

.45s

cubic-bezier(.2,.8,.2,1);

}

.media-converter:hover

.flow-arrow {

transform:

translate(

-43%,

-50%

);

}

/* =========================================================

FORMAT

========================================================= */

.media-converter .format-card {

min-height:

clamp(

75px,

10vw,

135px

);

padding:

10%;

display: flex;

flex-direction: column;

justify-content: center;

border-radius:

clamp(

10px,

1.4vw,

18px

);

background:

#111114;

box-shadow:

0

15px

35px

rgba(0,0,0,.14);

transition:

transform

.45s

cubic-bezier(.2,.8,.2,1);

}

.media-converter:hover

.format-card {

transform:

translateY(-3px);

}

.media-converter .format-label {

color:

rgba(255,255,255,.28);

font-size:

clamp(

3px,

.42vw,

6px

);

font-weight: 650;

letter-spacing: .13em;

}

.media-converter .format-name {

margin-top: 9%;

color: #fff;

font-size:

clamp(

16px,

2.3vw,

32px

);

line-height: .9;

font-weight: 760;

letter-spacing: -.065em;

}

.media-converter .format-codec {

margin-top: 10%;

color:

rgba(255,255,255,.35);

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

PROGRESS

========================================================= */

.media-converter .converter-progress {

margin-bottom: 5%;

}

.media-converter .progress-head {

margin-bottom: 2.5%;

display: flex;

justify-content: space-between;

color:

rgba(0,0,0,.34);

font-size:

clamp(

4px,

.5vw,

7px

);

}

.media-converter .progress-track {

position: relative;

height:

clamp(

3px,

.38vw,

5px

);

overflow: hidden;

border-radius: 999px;

background:

rgba(0,0,0,.07);

}

.media-converter .progress-fill {

position: absolute;

left: 0;

top: 0;

bottom: 0;

width: 72%;

border-radius: inherit;

background: #111;

transition:

width

1s

cubic-bezier(.2,.8,.2,1);

}

.media-converter:hover

.progress-fill {

width: 88%;

}

/* =========================================================

BOTTOM

========================================================= */

.media-converter .converter-bottom {

display: flex;

align-items: center;

justify-content: space-between;

gap: 10%;

}

.media-converter .privacy-note {

display: flex;

align-items: center;

gap:

clamp(

4px,

.5vw,

7px

);

color:

rgba(0,0,0,.34);

font-size:

clamp(

4px,

.5vw,

7px

);

}

.media-converter .privacy-dot {

width:

clamp(

4px,

.45vw,

6px

);

aspect-ratio: 1;

border-radius: 50%;

background: #4bae6c;

box-shadow:

0

0

0

4px

rgba(75,174,108,.08);

}

/* =========================================================

SAVE

========================================================= */

.media-converter .save-button {

min-height:

clamp(

26px,

3vw,

41px

);

padding:

0

7%;

display: flex;

align-items: center;

justify-content: center;

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.58vw,

8px

);

font-weight: 620;

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1),

box-shadow

.4s

cubic-bezier(.2,.8,.2,1);

}

.media-converter:hover

.save-button {

transform:

translateY(-2px);

box-shadow:

0

8px

22px

rgba(0,0,0,.16);

}

/* =========================================================

SCAN LIGHT

========================================================= */

.media-converter .converter-window::after {

content: "";

position: absolute;

top: -60%;

left: -60%;

width: 28%;

height: 220%;

transform:

rotate(18deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.36),

transparent

);

opacity: .3;

transition:

left

1.2s

cubic-bezier(.2,.8,.2,1);

pointer-events: none;

}

.media-converter:hover

.converter-window::after {

left: 130%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: internet-check

Название: Проверка интернета

Категория: Сервис

Порядок списка: 4

Главная: нет

NEW: нет

Статус: готов

Коротко: Проверка скорости, задержки и качества интернет-соединения прямо в браузере.

Класс визуала: internet-check

DESCRIPTION

Небольшой браузерный инструмент для быстрой проверки интернет-соединения. Показывает основные параметры сети: скорость загрузки и отдачи, задержку и общее состояние соединения. Сделал его как простой инструмент без лишних экранов, рекламы и перегруженного интерфейса.

ENDDESCRIPTION

VISUAL_HTML

<div class="net-window">

<div class="net-header">

<div class="net-title">

internet

</div>

<div class="net-status">

<span class="status-dot"></span>

подключено

</div>

</div>

<div class="net-main">

<div class="speed-circle">

<div class="speed-ring">

<div class="speed-progress"></div>

</div>

<div class="speed-center">

<div class="speed-number">

487

</div>

<div class="speed-unit">

Мбит/с

</div>

</div>

<div class="needle"></div>

</div>

<div class="net-metrics">

<div class="metric">

<div class="metric-label">

DOWNLOAD

</div>

<div class="metric-value">

487

<span>Mbps</span>

</div>

</div>

<div class="metric">

<div class="metric-label">

UPLOAD

</div>

<div class="metric-value">

128

<span>Mbps</span>

</div>

</div>

<div class="metric">

<div class="metric-label">

PING

</div>

<div class="metric-value">

12

<span>ms</span>

</div>

</div>

</div>

</div>

<div class="connection-chart">

<div class="chart-line">

<span class="p1"></span>

<span class="p2"></span>

<span class="p3"></span>

<span class="p4"></span>

<span class="p5"></span>

<span class="p6"></span>

<span class="p7"></span>

</div>

<div class="chart-caption">

стабильность соединения

</div>

</div>

<div class="net-footer">

<div class="server">

сервер автоматически

</div>

<div class="repeat-button">

Проверить ещё раз

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.internet-check {

background:

radial-gradient(

circle at 50% 44%,

#27292d,

#111214 52%,

#070708 100%

);

}

/* =========================================================

WINDOW

========================================================= */

.internet-check .net-window {

position: absolute;

inset: 7%;

padding:

5%

6%;

display: flex;

flex-direction: column;

overflow: hidden;

border:

1px solid

rgba(255,255,255,.09);

border-radius:

clamp(

16px,

2vw,

28px

);

background:

linear-gradient(

150deg,

rgba(31,32,36,.96),

rgba(12,13,15,.98)

);

box-shadow:

0

35px

100px

rgba(0,0,0,.42);

transform:

perspective(1100px)

rotateX(.8deg)

rotateY(-1.5deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.internet-check:hover

.net-window {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

42px

115px

rgba(0,0,0,.5);

}

/* =========================================================

HEADER

========================================================= */

.internet-check .net-header {

display: flex;

align-items: center;

justify-content: space-between;

}

.internet-check .net-title {

color: #fff;

font-size:

clamp(

10px,

1.4vw,

20px

);

font-weight: 750;

letter-spacing: -.055em;

}

.internet-check .net-status {

display: flex;

align-items: center;

gap:

clamp(

4px,

.5vw,

7px

);

color:

rgba(255,255,255,.34);

font-size:

clamp(

4px,

.48vw,

7px

);

}

.internet-check .status-dot {

width:

clamp(

4px,

.45vw,

6px

);

aspect-ratio: 1;

border-radius: 50%;

background: #5ed47d;

box-shadow:

0

0

0

4px

rgba(94,212,125,.08);

animation:

netStatus

1.6s

ease-in-out

infinite;

}

@keyframes netStatus {

50% {

opacity: .45;

}

}

/* =========================================================

MAIN

========================================================= */

.internet-check .net-main {

margin:

auto

0;

display: grid;

grid-template-columns:

43%

57%;

align-items: center;

}

/* =========================================================

SPEED CIRCLE

========================================================= */

.internet-check .speed-circle {

position: relative;

width: 72%;

aspect-ratio: 1;

margin-left: 7%;

}

.internet-check .speed-ring {

position: absolute;

inset: 0;

border:

clamp(

5px,

.7vw,

10px

)

solid

rgba(255,255,255,.07);

border-radius: 50%;

}

.internet-check .speed-progress {

position: absolute;

inset:

calc(

clamp(

5px,

.7vw,

10px

)

* -1

);

border:

clamp(

5px,

.7vw,

10px

)

solid

transparent;

border-top-color:

rgba(255,255,255,.92);

border-right-color:

rgba(255,255,255,.92);

border-bottom-color:

rgba(255,255,255,.34);

border-radius: 50%;

transform:

rotate(36deg);

transition:

transform

1.1s

cubic-bezier(.2,.8,.2,1);

}

.internet-check:hover

.speed-progress {

transform:

rotate(68deg);

}

/* =========================================================

CENTER

========================================================= */

.internet-check .speed-center {

position: absolute;

left: 50%;

top: 50%;

transform:

translate(

-50%,

-50%

);

text-align: center;

}

.internet-check .speed-number {

color: #fff;

font-size:

clamp(

21px,

3.4vw,

48px

);

line-height: .9;

font-weight: 680;

letter-spacing: -.075em;

}

.internet-check .speed-unit {

margin-top: 10%;

color:

rgba(255,255,255,.28);

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

NEEDLE

========================================================= */

.internet-check .needle {

position: absolute;

left: 50%;

top: 50%;

width: 40%;

height: 1px;

transform:

rotate(-16deg);

transform-origin:

left center;

background:

linear-gradient(

90deg,

rgba(255,255,255,.72),

transparent

);

transition:

transform

1.1s

cubic-bezier(.2,.8,.2,1);

}

.internet-check:hover

.needle {

transform:

rotate(22deg);

}

/* =========================================================

METRICS

========================================================= */

.internet-check .net-metrics {

display: grid;

grid-template-columns:

repeat(

3,

1fr

);

gap: 6%;

}

.internet-check .metric {

min-width: 0;

}

.internet-check .metric-label {

margin-bottom: 16%;

color:

rgba(255,255,255,.24);

font-size:

clamp(

3px,

.42vw,

6px

);

font-weight: 650;

letter-spacing: .11em;

}

.internet-check .metric-value {

color:

rgba(255,255,255,.92);

font-size:

clamp(

9px,

1.4vw,

20px

);

line-height: 1;

font-weight: 640;

letter-spacing: -.045em;

}

.internet-check .metric-value span {

display: block;

margin-top: 10%;

color:

rgba(255,255,255,.26);

font-size:

.38em;

font-weight: 450;

letter-spacing: 0;

}

/* =========================================================

CHART

========================================================= */

.internet-check .connection-chart {

margin-top: auto;

padding-top: 5%;

border-top:

1px solid

rgba(255,255,255,.06);

}

.internet-check .chart-line {

height:

clamp(

25px,

3.8vw,

52px

);

display: flex;

align-items: flex-end;

gap: 1.8%;

}

.internet-check .chart-line span {

flex: 1;

border-radius:

3px

3px

0

0;

background:

rgba(255,255,255,.11);

transition:

height

.7s

cubic-bezier(.2,.8,.2,1),

background

.7s

ease;

}

.internet-check .p1 {

height: 42%;

}

.internet-check .p2 {

height: 67%;

}

.internet-check .p3 {

height: 56%;

}

.internet-check .p4 {

height: 82%;

}

.internet-check .p5 {

height: 74%;

}

.internet-check .p6 {

height: 92%;

}

.internet-check .p7 {

height: 78%;

}

.internet-check:hover

.p1 {

height: 63%;

}

.internet-check:hover

.p2 {

height: 78%;

}

.internet-check:hover

.p3 {

height: 73%;

}

.internet-check:hover

.p4 {

height: 91%;

}

.internet-check:hover

.p5 {

height: 83%;

}

.internet-check:hover

.p6 {

height: 96%;

background:

rgba(255,255,255,.32);

}

.internet-check:hover

.p7 {

height: 89%;

}

.internet-check .chart-caption {

margin-top: 2%;

color:

rgba(255,255,255,.20);

font-size:

clamp(

3px,

.4vw,

6px

);

}

/* =========================================================

FOOTER

========================================================= */

.internet-check .net-footer {

margin-top: 4%;

display: flex;

align-items: center;

justify-content: space-between;

}

.internet-check .server {

color:

rgba(255,255,255,.21);

font-size:

clamp(

3px,

.43vw,

6px

);

}

.internet-check .repeat-button {

min-height:

clamp(

22px,

2.7vw,

36px

);

padding:

0

5%;

display: flex;

align-items: center;

justify-content: center;

border:

1px solid

rgba(255,255,255,.12);

border-radius: 999px;

background:

rgba(255,255,255,.055);

color:

rgba(255,255,255,.7);

font-size:

clamp(

4px,

.5vw,

7px

);

transition:

background .35s ease,

transform .35s ease;

}

.internet-check:hover

.repeat-button {

background:

rgba(255,255,255,.1);

transform:

translateY(-2px);

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: youtube-downloader

Название: YouTube Downloader

Категория: Расширение

Порядок списка: 2

Главная: нет

NEW: да

Статус: личный инструмент

Коротко: Браузерное расширение для сохранения видео и аудио с YouTube.

Класс визуала: youtube-downloader

DESCRIPTION

Моё браузерное расширение для сохранения видео и аудио с YouTube. Добавляет простой интерфейс выбора формата и качества прямо рядом с видео, а обработка выполняется локально через связку браузера и инструментов на компьютере. Сделал его прежде всего для собственного рабочего процесса, чтобы быстрее сохранять нужные материалы для монтажа и работы.

ENDDESCRIPTION

VISUAL_HTML

<div class="yt-window">

<div class="yt-video">

<div class="video-image">

<div class="video-gradient"></div>

<div class="video-play">

<span></span>

</div>

<div class="video-time">

12:48

</div>

</div>

<div class="video-info">

<div class="video-title">

Wedding Film

</div>

<div class="video-meta">

YouTube · 4K

</div>

</div>

</div>

<div class="download-panel">

<div class="panel-top">

<div class="panel-title">

Скачать

</div>

<div class="extension-badge">

VVRSHN

</div>

</div>

<div class="format-label">

ВИДЕО

</div>

<div class="quality-list">

<div class="quality-row">

<div>

<div class="quality-name">

2160p

</div>

<div class="quality-meta">

MP4 · 4K

</div>

</div>

<div class="quality-size">

842 MB

</div>

</div>

<div class="quality-row active">

<div>

<div class="quality-name">

1080p

</div>

<div class="quality-meta">

MP4 · Full HD

</div>

</div>

<div class="quality-check">

</div>

</div>

<div class="quality-row">

<div>

<div class="quality-name">

720p

</div>

<div class="quality-meta">

MP4 · HD

</div>

</div>

<div class="quality-size">

214 MB

</div>

</div>

</div>

<div class="format-divider"></div>

<div class="audio-row">

<div>

<div class="format-label">

АУДИО

</div>

<div class="audio-name">

MP3

</div>

</div>

<div class="audio-wave">

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

</div>

</div>

<div class="download-button">

<span class="download-icon">

</span>

Скачать

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.youtube-downloader {

background:

linear-gradient(

145deg,

#e9e9e7,

#f5f5f2

);

}

/* =========================================================

WINDOW

========================================================= */

.youtube-downloader .yt-window {

position: absolute;

inset: 7%;

display: grid;

grid-template-columns:

60%

40%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background: #fff;

box-shadow:

0

32px

90px

rgba(0,0,0,.14);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.4deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.youtube-downloader:hover

.yt-window {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

40px

110px

rgba(0,0,0,.18);

}

/* =========================================================

VIDEO SIDE

========================================================= */

.youtube-downloader .yt-video {

position: relative;

padding:

8%;

display: flex;

flex-direction: column;

background:

#f3f3f1;

}

/* =========================================================

VIDEO IMAGE

========================================================= */

.youtube-downloader .video-image {

position: relative;

flex: 1;

overflow: hidden;

border-radius:

clamp(

10px,

1.3vw,

18px

);

background:

linear-gradient(

135deg,

#323035,

#76695d 35%,

#c3ab94 63%,

#545158

);

box-shadow:

0

15px

40px

rgba(0,0,0,.13);

}

.youtube-downloader .video-image::before {

content: "";

position: absolute;

left: 13%;

bottom: -8%;

width: 28%;

height: 76%;

border-radius:

50%

50%

10%

10%;

background:

rgba(20,20,22,.64);

transform:

rotate(-5deg);

}

.youtube-downloader .video-image::after {

content: "";

position: absolute;

right: 13%;

bottom: -8%;

width: 30%;

height: 80%;

border-radius:

50%

50%

10%

10%;

background:

rgba(245,240,232,.68);

transform:

rotate(5deg);

}

.youtube-downloader .video-gradient {

position: absolute;

z-index: 3;

inset: 0;

background:

linear-gradient(

180deg,

rgba(0,0,0,.03),

rgba(0,0,0,.28)

);

}

/* =========================================================

PLAY

========================================================= */

.youtube-downloader .video-play {

position: absolute;

z-index: 10;

left: 50%;

top: 50%;

width:

clamp(

31px,

4vw,

55px

);

aspect-ratio: 1;

display: grid;

place-items: center;

transform:

translate(

-50%,

-50%

);

border-radius: 50%;

background:

rgba(255,255,255,.91);

box-shadow:

0

8px

28px

rgba(0,0,0,.16);

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1);

}

.youtube-downloader:hover

.video-play {

transform:

translate(

-50%,

-50%

)

scale(1.07);

}

.youtube-downloader .video-play span {

width: 0;

height: 0;

margin-left: 7%;

border-top:

clamp(

4px,

.55vw,

7px

)

solid

transparent;

border-bottom:

clamp(

4px,

.55vw,

7px

)

solid

transparent;

border-left:

clamp(

7px,

.85vw,

11px

)

solid

#111;

}

/* =========================================================

TIME

========================================================= */

.youtube-downloader .video-time {

position: absolute;

z-index: 10;

right: 4%;

bottom: 5%;

padding:

1.4%

2.5%;

border-radius: 4px;

background:

rgba(0,0,0,.68);

color: #fff;

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

VIDEO INFO

========================================================= */

.youtube-downloader .video-info {

padding-top: 7%;

}

.youtube-downloader .video-title {

color: #111;

font-size:

clamp(

8px,

1.15vw,

16px

);

font-weight: 680;

letter-spacing: -.04em;

}

.youtube-downloader .video-meta {

margin-top: 3%;

color:

rgba(0,0,0,.30);

font-size:

clamp(

4px,

.5vw,

7px

);

}

/* =========================================================

DOWNLOAD PANEL

========================================================= */

.youtube-downloader .download-panel {

position: relative;

padding:

11%

10%;

display: flex;

flex-direction: column;

border-left:

1px solid

rgba(0,0,0,.07);

background: #fff;

}

/* =========================================================

PANEL TOP

========================================================= */

.youtube-downloader .panel-top {

display: flex;

align-items: center;

justify-content: space-between;

}

.youtube-downloader .panel-title {

color: #111;

font-size:

clamp(

8px,

1.05vw,

15px

);

font-weight: 680;

letter-spacing: -.04em;

}

.youtube-downloader .extension-badge {

padding:

2%

4%;

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

3px,

.36vw,

5px

);

font-weight: 700;

letter-spacing: .11em;

}

/* =========================================================

FORMAT

========================================================= */

.youtube-downloader .format-label {

margin-top: 15%;

color:

rgba(0,0,0,.25);

font-size:

clamp(

3px,

.4vw,

6px

);

font-weight: 700;

letter-spacing: .14em;

}

/* =========================================================

QUALITY

========================================================= */

.youtube-downloader .quality-list {

margin-top: 6%;

}

.youtube-downloader .quality-row {

min-height:

clamp(

31px,

4vw,

54px

);

padding:

0

6%;

display: flex;

align-items: center;

justify-content: space-between;

border-bottom:

1px solid

rgba(0,0,0,.06);

}

.youtube-downloader .quality-row.active {

margin:

2%

-2%;

padding:

0

8%;

border: 0;

border-radius:

clamp(

7px,

.9vw,

12px

);

background:

#f3f3f1;

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1);

}

.youtube-downloader:hover

.quality-row.active {

transform:

translateX(3px);

}

.youtube-downloader .quality-name {

color:

rgba(0,0,0,.72);

font-size:

clamp(

5px,

.65vw,

9px

);

font-weight: 620;

}

.youtube-downloader .quality-meta {

margin-top: 5%;

color:

rgba(0,0,0,.25);

font-size:

clamp(

3px,

.38vw,

5.5px

);

}

.youtube-downloader .quality-size {

color:

rgba(0,0,0,.23);

font-size:

clamp(

3px,

.4vw,

6px

);

}

.youtube-downloader .quality-check {

width:

clamp(

14px,

1.7vw,

23px

);

aspect-ratio: 1;

display: grid;

place-items: center;

border-radius: 50%;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.55vw,

8px

);

}

/* =========================================================

DIVIDER

========================================================= */

.youtube-downloader .format-divider {

height: 1px;

margin-top: 8%;

background:

rgba(0,0,0,.07);

}

/* =========================================================

AUDIO

========================================================= */

.youtube-downloader .audio-row {

display: flex;

align-items: flex-end;

justify-content: space-between;

}

.youtube-downloader .audio-row

.format-label {

margin-top: 14%;

}

.youtube-downloader .audio-name {

margin-top: 16%;

color: #111;

font-size:

clamp(

7px,

.9vw,

13px

);

font-weight: 680;

}

.youtube-downloader .audio-wave {

height:

clamp(

20px,

2.7vw,

36px

);

display: flex;

align-items: center;

gap:

clamp(

2px,

.25vw,

4px

);

}

.youtube-downloader .audio-wave span {

width:

clamp(

2px,

.23vw,

3px

);

border-radius: 999px;

background:

rgba(0,0,0,.20);

animation:

ytWave

1.3s

ease-in-out

infinite;

}

.youtube-downloader .audio-wave span:nth-child(1) {

height: 25%;

}

.youtube-downloader .audio-wave span:nth-child(2) {

height: 55%;

animation-delay: -.2s;

}

.youtube-downloader .audio-wave span:nth-child(3) {

height: 85%;

animation-delay: -.4s;

}

.youtube-downloader .audio-wave span:nth-child(4) {

height: 45%;

animation-delay: -.6s;

}

.youtube-downloader .audio-wave span:nth-child(5) {

height: 72%;

animation-delay: -.8s;

}

.youtube-downloader .audio-wave span:nth-child(6) {

height: 38%;

animation-delay: -1s;

}

.youtube-downloader .audio-wave span:nth-child(7) {

height: 62%;

animation-delay: -1.2s;

}

@keyframes ytWave {

50% {

transform:

scaleY(.45);

}

}

/* =========================================================

DOWNLOAD BUTTON

========================================================= */

.youtube-downloader .download-button {

min-height:

clamp(

28px,

3.5vw,

47px

);

margin-top: auto;

display: flex;

align-items: center;

justify-content: center;

gap:

clamp(

5px,

.6vw,

8px

);

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.58vw,

8px

);

font-weight: 620;

transition:

transform

.4s

cubic-bezier(.2,.8,.2,1),

box-shadow

.4s

cubic-bezier(.2,.8,.2,1);

}

.youtube-downloader:hover

.download-button {

transform:

translateY(-2px);

box-shadow:

0

9px

24px

rgba(0,0,0,.16);

}

.youtube-downloader .download-icon {

font-size:

1.25em;

transform:

translateY(-1px);

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: vvrshn-adblock

Название: VVRSHN AdBlock

Категория: Расширение

Порядок списка: 3

Главная: нет

NEW: да

Статус: beta

Коротко: Моё браузерное расширение, которое автоматически находит рекламу на сайтах и аккуратно скрывает её.

Класс визуала: vvrshn-adblock

DESCRIPTION

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

ENDDESCRIPTION

VISUAL_HTML

<div class="adblock-browser">

<div class="browser-top">

<div class="browser-dots">

<span></span>

<span></span>

<span></span>

</div>

<div class="browser-address">

mail.example.ru

</div>

<div class="shield-mini">

</div>

</div>

<div class="browser-body">

<div class="mail-sidebar">

<div class="mail-logo"></div>

<div class="side-line active"></div>

<div class="side-line"></div>

<div class="side-line short"></div>

<div class="side-line"></div>

<div class="side-line short"></div>

</div>

<div class="mail-content">

<div class="mail-toolbar">

<div class="toolbar-line"></div>

<div class="toolbar-icons">

<span></span>

<span></span>

<span></span>

</div>

</div>

<div class="messages">

<div class="message-row">

<span class="avatar"></span>

<div class="message-copy">

<span></span>

<span></span>

</div>

</div>

<div class="message-row">

<span class="avatar"></span>

<div class="message-copy">

<span></span>

<span></span>

</div>

</div>

<div class="message-row">

<span class="avatar"></span>

<div class="message-copy">

<span></span>

<span></span>

</div>

</div>

<div class="message-row">

<span class="avatar"></span>

<div class="message-copy">

<span></span>

<span></span>

</div>

</div>

</div>

</div>

<div class="ads-column">

<div class="ad-card ad-one">

<div class="ad-label">

РЕКЛАМА

</div>

<div class="ad-picture"></div>

<div class="ad-lines">

<span></span>

<span></span>

</div>

<div class="blocked-cross"></div>

</div>

<div class="ad-card ad-two">

<div class="ad-label">

РЕКЛАМА

</div>

<div class="ad-lines">

<span></span>

<span></span>

<span></span>

</div>

<div class="blocked-cross"></div>

</div>

</div>

<div class="clean-column">

<div class="clean-message">

<div class="clean-icon">

</div>

<div>

реклама<br>

скрыта

</div>

</div>

</div>

</div>

<div class="adblock-panel">

<div class="panel-icon">

V

</div>

<div class="panel-copy">

<div class="panel-title">

VVRSHN AdBlock

</div>

<div class="panel-status">

Защита включена

</div>

</div>

<div class="toggle active">

<div class="toggle-point"></div>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.vvrshn-adblock {

background:

linear-gradient(

145deg,

#e9e9e7,

#f4f4f1

);

}

/* =========================================================

BROWSER

========================================================= */

.vvrshn-adblock .adblock-browser {

position: absolute;

inset: 7%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background: #fff;

box-shadow:

0

32px

90px

rgba(0,0,0,.14);

transform:

perspective(1100px)

rotateX(.8deg)

rotateY(-1.4deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.vvrshn-adblock:hover

.adblock-browser {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

42px

110px

rgba(0,0,0,.18);

}

/* =========================================================

TOP

========================================================= */

.vvrshn-adblock .browser-top {

position: relative;

height: 12%;

min-height: 25px;

padding:

0

3%;

display: flex;

align-items: center;

border-bottom:

1px solid

rgba(0,0,0,.06);

background:

#f3f3f1;

}

.vvrshn-adblock .browser-dots {

display: flex;

gap:

clamp(

3px,

.35vw,

5px

);

}

.vvrshn-adblock .browser-dots span {

width:

clamp(

4px,

.48vw,

6px

);

aspect-ratio: 1;

border-radius: 50%;

background:

rgba(0,0,0,.15);

}

.vvrshn-adblock .browser-address {

position: absolute;

left: 50%;

width: 43%;

min-height:

clamp(

14px,

1.8vw,

24px

);

transform:

translateX(-50%);

display: flex;

align-items: center;

justify-content: center;

border:

1px solid

rgba(0,0,0,.05);

border-radius: 999px;

background:

rgba(255,255,255,.72);

color:

rgba(0,0,0,.28);

font-size:

clamp(

3px,

.42vw,

6px

);

}

.vvrshn-adblock .shield-mini {

margin-left: auto;

width:

clamp(

15px,

1.8vw,

25px

);

aspect-ratio: 1;

display: grid;

place-items: center;

border-radius: 7px;

background: #111;

color: #fff;

font-size:

clamp(

5px,

.55vw,

8px

);

font-weight: 700;

}

/* =========================================================

BODY

========================================================= */

.vvrshn-adblock .browser-body {

position: absolute;

left: 0;

right: 0;

top: 12%;

bottom: 0;

display: grid;

grid-template-columns:

18%

54%

28%;

}

/* =========================================================

SIDEBAR

========================================================= */

.vvrshn-adblock .mail-sidebar {

padding:

12%

14%;

border-right:

1px solid

rgba(0,0,0,.055);

background:

#f7f7f5;

}

.vvrshn-adblock .mail-logo {

width: 36%;

aspect-ratio: 1;

margin-bottom: 24%;

border-radius:

35%;

background: #111;

}

.vvrshn-adblock .side-line {

width: 82%;

height:

clamp(

3px,

.38vw,

5px

);

margin-bottom: 14%;

border-radius: 999px;

background:

rgba(0,0,0,.08);

}

.vvrshn-adblock .side-line.short {

width: 58%;

}

.vvrshn-adblock .side-line.active {

width: 92%;

background:

rgba(0,0,0,.32);

}

/* =========================================================

MAIL CONTENT

========================================================= */

.vvrshn-adblock .mail-content {

background: #fff;

}

.vvrshn-adblock .mail-toolbar {

height: 16%;

padding:

0

6%;

display: flex;

align-items: center;

justify-content: space-between;

border-bottom:

1px solid

rgba(0,0,0,.055);

}

.vvrshn-adblock .toolbar-line {

width: 27%;

height: 5px;

border-radius: 999px;

background:

rgba(0,0,0,.08);

}

.vvrshn-adblock .toolbar-icons {

display: flex;

gap:

clamp(

5px,

.65vw,

9px

);

}

.vvrshn-adblock .toolbar-icons span {

width:

clamp(

9px,

1.1vw,

15px

);

aspect-ratio: 1;

border:

1px solid

rgba(0,0,0,.08);

border-radius: 50%;

}

/* =========================================================

MESSAGES

========================================================= */

.vvrshn-adblock .messages {

padding:

3%

5%;

}

.vvrshn-adblock .message-row {

height:

clamp(

30px,

4vw,

54px

);

display: flex;

align-items: center;

gap: 5%;

border-bottom:

1px solid

rgba(0,0,0,.045);

}

.vvrshn-adblock .avatar {

width:

clamp(

14px,

1.8vw,

24px

);

aspect-ratio: 1;

flex: 0 0 auto;

border-radius: 50%;

background:

#ededeb;

}

.vvrshn-adblock .message-copy {

width: 70%;

display: flex;

flex-direction: column;

gap:

clamp(

3px,

.35vw,

5px

);

}

.vvrshn-adblock .message-copy span {

width: 100%;

height: 4px;

border-radius: 999px;

background:

rgba(0,0,0,.09);

}

.vvrshn-adblock .message-copy span:last-child {

width: 63%;

opacity: .6;

}

/* =========================================================

ADS

========================================================= */

.vvrshn-adblock .ads-column {

position: relative;

padding:

8%;

overflow: hidden;

border-left:

1px solid

rgba(0,0,0,.055);

background:

#f7f7f5;

transition:

opacity

.6s

ease,

transform

.6s

cubic-bezier(.2,.8,.2,1),

filter

.6s

ease;

}

.vvrshn-adblock:hover

.ads-column {

opacity: 0;

filter:

blur(8px);

transform:

scale(.92)

translateX(20%);

}

.vvrshn-adblock .ad-card {

position: relative;

margin-bottom: 9%;

padding:

9%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

8px,

1vw,

13px

);

background: #fff;

}

.vvrshn-adblock .ad-one {

height: 52%;

}

.vvrshn-adblock .ad-two {

height: 31%;

}

.vvrshn-adblock .ad-label {

color:

rgba(0,0,0,.28);

font-size:

clamp(

3px,

.35vw,

5px

);

letter-spacing: .13em;

}

.vvrshn-adblock .ad-picture {

height: 43%;

margin-top: 9%;

border-radius:

6px;

background:

linear-gradient(

135deg,

#e2c19f,

#ba8d68

);

}

.vvrshn-adblock .ad-lines {

margin-top: 10%;

display: flex;

flex-direction: column;

gap: 5px;

}

.vvrshn-adblock .ad-lines span {

width: 100%;

height: 4px;

border-radius: 999px;

background:

rgba(0,0,0,.08);

}

.vvrshn-adblock .ad-lines span:nth-child(2) {

width: 66%;

}

.vvrshn-adblock .ad-lines span:nth-child(3) {

width: 43%;

}

/* =========================================================

BLOCK CROSS

========================================================= */

.vvrshn-adblock .blocked-cross {

position: absolute;

z-index: 10;

left: 50%;

top: 50%;

width:

clamp(

29px,

4vw,

53px

);

aspect-ratio: 1;

transform:

translate(

-50%,

-50%

);

border-radius: 50%;

background:

rgba(15,15,17,.90);

box-shadow:

0

9px

25px

rgba(0,0,0,.20);

}

.vvrshn-adblock .blocked-cross::before,

.vvrshn-adblock .blocked-cross::after {

content: "";

position: absolute;

left: 24%;

right: 24%;

top: 50%;

height: 2px;

border-radius: 999px;

background: #fff;

}

.vvrshn-adblock .blocked-cross::before {

transform:

rotate(45deg);

}

.vvrshn-adblock .blocked-cross::after {

transform:

rotate(-45deg);

}

/* =========================================================

CLEAN STATE

========================================================= */

.vvrshn-adblock .clean-column {

position: absolute;

z-index: 15;

right: 0;

top: 0;

bottom: 0;

width: 28%;

display: flex;

align-items: center;

justify-content: center;

opacity: 0;

transform:

translateX(25%);

background:

#f7f7f5;

transition:

opacity

.65s

ease

.08s,

transform

.65s

cubic-bezier(.2,.8,.2,1)

.08s;

}

.vvrshn-adblock:hover

.clean-column {

opacity: 1;

transform:

translateX(0);

}

.vvrshn-adblock .clean-message {

display: flex;

flex-direction: column;

align-items: center;

gap:

clamp(

7px,

.9vw,

12px

);

color:

rgba(0,0,0,.38);

font-size:

clamp(

5px,

.58vw,

8px

);

line-height: 1.3;

text-align: center;

}

.vvrshn-adblock .clean-icon {

width:

clamp(

30px,

4vw,

54px

);

aspect-ratio: 1;

display: grid;

place-items: center;

border-radius: 50%;

background: #111;

color: #fff;

font-size:

clamp(

9px,

1.2vw,

16px

);

box-shadow:

0

10px

30px

rgba(0,0,0,.14);

}

/* =========================================================

FLOATING EXTENSION PANEL

========================================================= */

.vvrshn-adblock .adblock-panel {

position: absolute;

z-index: 30;

right: 4%;

bottom: 6%;

width: 32%;

min-height:

clamp(

40px,

5.5vw,

73px

);

padding:

3%;

display: flex;

align-items: center;

gap: 7%;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

9px,

1.1vw,

15px

);

background:

rgba(255,255,255,.94);

box-shadow:

0

17px

45px

rgba(0,0,0,.14);

backdrop-filter:

blur(15px);

-webkit-backdrop-filter:

blur(15px);

transform:

translateY(8%)

scale(.98);

transition:

transform

.5s

cubic-bezier(.2,.8,.2,1);

}

.vvrshn-adblock:hover

.adblock-panel {

transform:

translateY(0)

scale(1);

}

.vvrshn-adblock .panel-icon {

width:

clamp(

24px,

3.2vw,

43px

);

aspect-ratio: 1;

flex: 0 0 auto;

display: grid;

place-items: center;

border-radius:

30%;

background: #111;

color: #fff;

font-size:

clamp(

7px,

.9vw,

12px

);

font-weight: 760;

}

.vvrshn-adblock .panel-copy {

min-width: 0;

flex: 1;

}

.vvrshn-adblock .panel-title {

overflow: hidden;

color: #111;

font-size:

clamp(

5px,

.62vw,

8.5px

);

font-weight: 650;

white-space: nowrap;

text-overflow: ellipsis;

}

.vvrshn-adblock .panel-status {

margin-top: 7%;

color:

rgba(0,0,0,.30);

font-size:

clamp(

3px,

.4vw,

5.5px

);

}

/* =========================================================

TOGGLE

========================================================= */

.vvrshn-adblock .toggle {

position: relative;

width:

clamp(

25px,

3vw,

41px

);

height:

clamp(

14px,

1.7vw,

23px

);

flex: 0 0 auto;

border-radius: 999px;

background:

rgba(0,0,0,.10);

}

.vvrshn-adblock .toggle.active {

background: #111;

}

.vvrshn-adblock .toggle-point {

position: absolute;

top: 50%;

right: 7%;

height: 76%;

aspect-ratio: 1;

transform:

translateY(-50%);

border-radius: 50%;

background: #fff;

box-shadow:

0

2px

7px

rgba(0,0,0,.16);

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: editors-catalog

Название: Каталог монтажёров

Категория: Сайт

Порядок списка: 5

Главная: нет

NEW: да

Статус: в разработке

Коротко: Каталог монтажёров с ценами, специализацией, примерами работ и контактами.

Класс визуала: editors-catalog

DESCRIPTION

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

ENDDESCRIPTION

VISUAL_HTML

<div class="editors-interface">

<div class="editors-header">

<div class="editors-brand">

монтажёры

</div>

<div class="editors-counter">

КАТАЛОГ

</div>

</div>

<div class="editors-grid">

<div class="editor-card editor-card-a">

<div class="editor-top">

<div class="editor-avatar">

М

</div>

<div class="editor-person">

<div class="editor-name">

muvistudio

</div>

<div class="editor-type">

студия монтажа

</div>

</div>

</div>

<div class="editor-speciality">

свадебные фильмы

</div>

<div class="editor-price">

<span>

фильм

</span>

<strong>

40 000 ₽

</strong>

</div>

<div class="editor-work">

<span class="work-play"></span>

<div class="work-lines">

<span></span>

<span></span>

</div>

</div>

</div>

<div class="editor-card editor-card-main">

<div class="editor-top">

<div class="editor-avatar dark">

A

</div>

<div class="editor-person">

<div class="editor-name">

монтажёр

</div>

<div class="editor-type">

авторский монтаж

</div>

</div>

<div class="available-dot"></div>

</div>

<div class="editor-tags">

<span>

фильмы

</span>

<span>

клипы

</span>

<span>

reels

</span>

</div>

<div class="editor-prices">

<div class="price-row">

<span>Фильм</span>

<strong>25 000 ₽</strong>

</div>

<div class="price-row">

<span>Клип</span>

<strong>8 000 ₽</strong>

</div>

<div class="price-row">

<span>Reels</span>

<strong>3 000 ₽</strong>

</div>

</div>

<div class="editor-contact">

посмотреть работы

<span>↗</span>

</div>

</div>

<div class="editor-card editor-card-b">

<div class="editor-top">

<div class="editor-avatar">

V

</div>

<div class="editor-person">

<div class="editor-name">

video editor

</div>

<div class="editor-type">

клипы / reels

</div>

</div>

</div>

<div class="editor-speciality">

динамичный монтаж

</div>

<div class="editor-price">

<span>

клип

</span>

<strong>

12 000 ₽

</strong>

</div>

<div class="editor-work second">

<span class="work-play"></span>

<div class="work-lines">

<span></span>

<span></span>

</div>

</div>

</div>

</div>

<div class="editors-footer">

<div class="random-note">

без рейтинга · порядок случайный

</div>

<div class="catalogue-line"></div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.editors-catalog {

background:

linear-gradient(

145deg,

#ececea,

#d8d8d4

);

}

/* =========================================================

INTERFACE

========================================================= */

.editors-catalog .editors-interface {

position: absolute;

inset: 7%;

padding:

5%

5%

4%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background:

#f8f8f5;

box-shadow:

0

32px

90px

rgba(0,0,0,.14);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.3deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.editors-catalog:hover

.editors-interface {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

42px

110px

rgba(0,0,0,.18);

}

/* =========================================================

HEADER

========================================================= */

.editors-catalog .editors-header {

display: flex;

align-items: center;

justify-content:

space-between;

}

.editors-catalog .editors-brand {

color: #111;

font-size:

clamp(

10px,

1.4vw,

20px

);

font-weight: 750;

letter-spacing:

-.055em;

}

.editors-catalog .editors-counter {

color:

rgba(0,0,0,.27);

font-size:

clamp(

3px,

.4vw,

6px

);

font-weight: 700;

letter-spacing:

.14em;

}

/* =========================================================

GRID

========================================================= */

.editors-catalog .editors-grid {

position: absolute;

left: 5%;

right: 5%;

top: 20%;

bottom: 13%;

perspective:

900px;

transform-style:

preserve-3d;

}

/* =========================================================

CARDS

========================================================= */

.editors-catalog .editor-card {

position: absolute;

top: 50%;

width: 31%;

height: 81%;

padding: 5%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

10px,

1.3vw,

18px

);

background: #fff;

box-shadow:

0

18px

45px

rgba(0,0,0,.10);

transition:

transform

.65s

cubic-bezier(.2,.8,.2,1),

opacity

.5s

ease,

filter

.5s

ease;

}

.editors-catalog .editor-card-main {

z-index: 10;

left: 50%;

width: 34%;

height: 92%;

transform:

translate(

-50%,

-50%

);

}

.editors-catalog .editor-card-a {

z-index: 4;

left: 1%;

opacity: .62;

filter:

brightness(.92);

transform:

translateY(-50%)

rotateY(8deg)

scale(.92);

}

.editors-catalog .editor-card-b {

z-index: 4;

right: 1%;

opacity: .62;

filter:

brightness(.92);

transform:

translateY(-50%)

rotateY(-8deg)

scale(.92);

}

.editors-catalog:hover

.editor-card-main {

transform:

translate(

-50%,

-52%

)

scale(1.025);

}

.editors-catalog:hover

.editor-card-a {

transform:

translateY(-50%)

translateX(-3%)

rotateY(5deg)

scale(.93);

}

.editors-catalog:hover

.editor-card-b {

transform:

translateY(-50%)

translateX(3%)

rotateY(-5deg)

scale(.93);

}

/* =========================================================

PERSON

========================================================= */

.editors-catalog .editor-top {

position: relative;

display: flex;

align-items: center;

gap: 8%;

}

.editors-catalog .editor-avatar {

width:

clamp(

22px,

3vw,

40px

);

aspect-ratio: 1;

flex:

0

0

auto;

display: grid;

place-items: center;

border-radius: 50%;

background:

#e7e7e3;

color:

rgba(0,0,0,.47);

font-size:

clamp(

6px,

.8vw,

11px

);

font-weight: 680;

}

.editors-catalog .editor-avatar.dark {

background: #111;

color: #fff;

}

.editors-catalog .editor-person {

min-width: 0;

}

.editors-catalog .editor-name {

overflow: hidden;

color: #111;

font-size:

clamp(

5px,

.68vw,

9.5px

);

font-weight: 660;

white-space: nowrap;

text-overflow: ellipsis;

}

.editors-catalog .editor-type {

margin-top: 7%;

color:

rgba(0,0,0,.28);

font-size:

clamp(

3px,

.4vw,

6px

);

white-space: nowrap;

}

.editors-catalog .available-dot {

position: absolute;

right: 0;

top: 10%;

width:

clamp(

5px,

.55vw,

7px

);

aspect-ratio: 1;

border-radius: 50%;

background:

#55a86c;

box-shadow:

0

0

0

4px

rgba(85,168,108,.09);

}

/* =========================================================

SPECIALITY

========================================================= */

.editors-catalog .editor-speciality {

margin-top: 15%;

color:

rgba(0,0,0,.32);

font-size:

clamp(

4px,

.48vw,

7px

);

}

/* =========================================================

TAGS

========================================================= */

.editors-catalog .editor-tags {

margin-top: 14%;

display: flex;

flex-wrap: wrap;

gap: 5%;

}

.editors-catalog .editor-tags span {

padding:

4%

6%;

border:

1px solid

rgba(0,0,0,.07);

border-radius: 999px;

background:

#f5f5f2;

color:

rgba(0,0,0,.46);

font-size:

clamp(

3px,

.38vw,

5.5px

);

}

/* =========================================================

SIMPLE PRICE

========================================================= */

.editors-catalog .editor-price {

margin-top: 13%;

padding-top: 11%;

display: flex;

align-items: flex-end;

justify-content:

space-between;

border-top:

1px solid

rgba(0,0,0,.06);

}

.editors-catalog .editor-price span {

color:

rgba(0,0,0,.30);

font-size:

clamp(

3px,

.4vw,

6px

);

}

.editors-catalog .editor-price strong {

color: #111;

font-size:

clamp(

5px,

.68vw,

9.5px

);

font-weight: 650;

white-space: nowrap;

}

/* =========================================================

PRICE LIST

========================================================= */

.editors-catalog .editor-prices {

margin-top: 13%;

}

.editors-catalog .price-row {

min-height:

clamp(

25px,

3.3vw,

44px

);

display: flex;

align-items: center;

justify-content:

space-between;

border-bottom:

1px solid

rgba(0,0,0,.055);

}

.editors-catalog .price-row span {

color:

rgba(0,0,0,.38);

font-size:

clamp(

4px,

.48vw,

7px

);

}

.editors-catalog .price-row strong {

color: #111;

font-size:

clamp(

4px,

.52vw,

7.5px

);

font-weight: 650;

}

/* =========================================================

EXAMPLE WORK

========================================================= */

.editors-catalog .editor-work {

position: absolute;

left: 5%;

right: 5%;

bottom: 6%;

height: 26%;

overflow: hidden;

border-radius:

clamp(

6px,

.8vw,

11px

);

background:

linear-gradient(

145deg,

#82776c,

#c4b5a6

);

}

.editors-catalog .editor-work.second {

background:

linear-gradient(

145deg,

#656a72,

#aab0b8

);

}

.editors-catalog .work-play {

position: absolute;

left: 12%;

top: 50%;

width:

clamp(

18px,

2.3vw,

31px

);

aspect-ratio: 1;

transform:

translateY(-50%);

border-radius: 50%;

background:

rgba(255,255,255,.88);

}

.editors-catalog .work-play::after {

content: "";

position: absolute;

left: 53%;

top: 50%;

transform:

translate(

-50%,

-50%

);

width: 0;

height: 0;

border-top:

3px solid

transparent;

border-bottom:

3px solid

transparent;

border-left:

5px solid

#111;

}

.editors-catalog .work-lines {

position: absolute;

left: 37%;

right: 10%;

top: 50%;

transform:

translateY(-50%);

display: flex;

flex-direction: column;

gap:

clamp(

3px,

.35vw,

5px

);

}

.editors-catalog .work-lines span {

height:

clamp(

2px,

.27vw,

4px

);

border-radius: 999px;

background:

rgba(255,255,255,.55);

}

.editors-catalog .work-lines span:last-child {

width: 58%;

opacity: .6;

}

/* =========================================================

CONTACT

========================================================= */

.editors-catalog .editor-contact {

min-height:

clamp(

25px,

3.2vw,

43px

);

margin-top: auto;

position: absolute;

left: 5%;

right: 5%;

bottom: 6%;

padding:

0

7%;

display: flex;

align-items: center;

justify-content:

space-between;

border-radius: 999px;

background: #111;

color: #fff;

font-size:

clamp(

4px,

.48vw,

7px

);

transition:

transform

.35s

cubic-bezier(.2,.8,.2,1),

box-shadow

.35s

ease;

}

.editors-catalog:hover

.editor-contact {

transform:

translateY(-2px);

box-shadow:

0

8px

20px

rgba(0,0,0,.14);

}

/* =========================================================

FOOTER

========================================================= */

.editors-catalog .editors-footer {

position: absolute;

left: 5%;

right: 5%;

bottom: 4%;

display: flex;

align-items: center;

gap: 5%;

}

.editors-catalog .random-note {

flex:

0

0

auto;

color:

rgba(0,0,0,.24);

font-size:

clamp(

3px,

.38vw,

5.5px

);

}

.editors-catalog .catalogue-line {

flex: 1;

height: 1px;

background:

rgba(0,0,0,.07);

}

/* =========================================================

LIGHT SWEEP

========================================================= */

.editors-catalog

.editors-interface::after {

content: "";

position: absolute;

z-index: 30;

top: -70%;

left: -55%;

width: 23%;

height: 240%;

transform:

rotate(18deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.24),

transparent

);

opacity: .26;

pointer-events: none;

transition:

left

1.15s

cubic-bezier(.2,.8,.2,1);

}

.editors-catalog:hover

.editors-interface::after {

left: 130%;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: gennady-mishakov

Название: Геннадий Мишаков

Категория: Сайт

Порядок списка: 7

Главная: нет

NEW: да

Статус: готов

Коротко: Интерактивный сайт-презентация ведущего, где каждый экран превращён в небольшую сцену.

Класс визуала: gennady-mishakov

DESCRIPTION

Интерактивный сайт-презентация ведущего Геннадия Мишакова. Вместо обычных фотографий и длинного текста сайт построен как последовательность небольших сцен: церемония, банкет, интерактивы, букет, микрофон и другие моменты мероприятия. На экранах можно нажимать на персонажей и предметы, запускать анимации и постепенно знакомиться с Геной через его работу.

ENDDESCRIPTION

VISUAL_HTML

<div class="gennady-stage">

<div class="stage-top">

<div class="gennady-name">

Геннадий<br>

Мишаков

</div>

<div class="slide-counter">

04 / 10

</div>

</div>

<div class="ceremony-scene">

<div class="scene-caption">

ЦЕРЕМОНИЯ

</div>

<div class="confetti confetti-one"></div>

<div class="confetti confetti-two"></div>

<div class="confetti confetti-three"></div>

<div class="gennady-character">

<div class="gennady-head">

<div class="gennady-hair"></div>

</div>

<div class="gennady-body">

<div class="red-necklace">

<span></span>

<span></span>

<span></span>

<span></span>

<span></span>

</div>

</div>

<div class="gennady-mic">

<span class="mic-head"></span>

<span class="mic-body"></span>

</div>

</div>

<div class="couple">

<div class="partner groom">

<span class="partner-head"></span>

<span class="partner-body"></span>

</div>

<div class="hearts">

<span>♥</span>

<span>♥</span>

<span>♥</span>

</div>

<div class="partner bride">

<span class="partner-head"></span>

<span class="partner-body"></span>

</div>

</div>

<div class="speech-bubble">

объявляю вас<br>

мужем и женой

</div>

</div>

<div class="interactive-row">

<div class="interaction active">

<div class="interaction-icon">

</div>

<div>

церемония

</div>

</div>

<div class="interaction">

<div class="interaction-icon">

</div>

<div>

банкет

</div>

</div>

<div class="interaction">

<div class="interaction-icon">

</div>

<div>

букет

</div>

</div>

<div class="interaction">

<div class="interaction-icon">

</div>

<div>

микрофон

</div>

</div>

</div>

<div class="stage-hint">

нажми на Гену

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.gennady-mishakov {

background:

linear-gradient(

145deg,

#f0ede8,

#d8d2ca

);

}

/* =========================================================

STAGE

========================================================= */

.gennady-mishakov .gennady-stage {

position: absolute;

inset: 6%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background:

#f7f4ef;

box-shadow:

0

32px

90px

rgba(0,0,0,.15);

transform:

perspective(1100px)

rotateX(.6deg)

rotateY(-1.2deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov:hover

.gennady-stage {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

42px

110px

rgba(0,0,0,.19);

}

/* =========================================================

TOP

========================================================= */

.gennady-mishakov .stage-top {

position: absolute;

z-index: 30;

left: 5%;

right: 5%;

top: 5%;

display: flex;

align-items: flex-start;

justify-content:

space-between;

}

.gennady-mishakov .gennady-name {

color: #111;

font-size:

clamp(

10px,

1.35vw,

19px

);

line-height: .9;

font-weight: 760;

letter-spacing:

-.055em;

}

.gennady-mishakov .slide-counter {

color:

rgba(0,0,0,.28);

font-size:

clamp(

3px,

.42vw,

6px

);

font-weight: 650;

letter-spacing:

.10em;

}

/* =========================================================

SCENE

========================================================= */

.gennady-mishakov .ceremony-scene {

position: absolute;

left: 5%;

right: 5%;

top: 18%;

bottom: 20%;

overflow: hidden;

border-radius:

clamp(

10px,

1.4vw,

19px

);

background:

linear-gradient(

180deg,

#dad6d0 0%,

#ebe7e1 63%,

#c7b7a7 64%,

#b9a898 100%

);

box-shadow:

inset

0

0

0

1px

rgba(0,0,0,.045);

}

.gennady-mishakov .ceremony-scene::before {

content: "";

position: absolute;

left: 8%;

right: 8%;

bottom: 35%;

height: 1px;

background:

rgba(0,0,0,.06);

}

.gennady-mishakov .ceremony-scene::after {

content: "";

position: absolute;

left: 50%;

top: 0;

width: 35%;

height: 100%;

transform:

translateX(-50%);

background:

radial-gradient(

ellipse at center,

rgba(255,255,255,.65),

transparent 67%

);

}

/* =========================================================

CAPTION

========================================================= */

.gennady-mishakov .scene-caption {

position: absolute;

z-index: 10;

left: 3.5%;

top: 5%;

color:

rgba(0,0,0,.26);

font-size:

clamp(

3px,

.40vw,

6px

);

font-weight: 700;

letter-spacing:

.15em;

}

/* =========================================================

GENNADY

========================================================= */

.gennady-mishakov .gennady-character {

position: absolute;

z-index: 12;

left: 28%;

bottom: 8%;

width: 17%;

height: 69%;

transform-origin:

50%

100%;

transition:

transform

.55s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov:hover

.gennady-character {

transform:

translateX(-9%)

rotate(-2deg);

}

/* =========================================================

HEAD

========================================================= */

.gennady-mishakov .gennady-head {

position: absolute;

z-index: 5;

left: 50%;

top: 0;

width: 44%;

aspect-ratio: .86;

transform:

translateX(-50%);

border-radius:

47%

47%

44%

44%;

background:

#d7b299;

}

.gennady-mishakov .gennady-hair {

position: absolute;

left: -28%;

right: -27%;

top: -24%;

height: 88%;

border-radius:

55%

55%

42%

42%;

background:

linear-gradient(

160deg,

#c8c2ba,

#8d8984

);

z-index: -1;

transform:

rotate(-3deg);

}

/* =========================================================

BODY

========================================================= */

.gennady-mishakov .gennady-body {

position: absolute;

left: 50%;

bottom: 0;

width: 78%;

height: 70%;

transform:

translateX(-50%);

border-radius:

40%

40%

12%

12%;

background:

linear-gradient(

180deg,

#f7f4ee,

#e4dfd8

);

box-shadow:

inset

0

0

0

1px

rgba(0,0,0,.06);

}

/* =========================================================

NECKLACE

========================================================= */

.gennady-mishakov .red-necklace {

position: absolute;

left: 50%;

top: 9%;

width: 52%;

height: 22%;

transform:

translateX(-50%);

display: flex;

justify-content:

space-between;

align-items: flex-end;

}

.gennady-mishakov .red-necklace span {

width:

clamp(

3px,

.35vw,

5px

);

aspect-ratio: 1;

border-radius: 50%;

background:

#a9342d;

}

.gennady-mishakov .red-necklace span:nth-child(1),

.gennady-mishakov .red-necklace span:nth-child(5) {

transform:

translateY(-45%);

}

.gennady-mishakov .red-necklace span:nth-child(2),

.gennady-mishakov .red-necklace span:nth-child(4) {

transform:

translateY(-10%);

}

/* =========================================================

MICROPHONE

========================================================= */

.gennady-mishakov .gennady-mic {

position: absolute;

z-index: 20;

right: -19%;

top: 43%;

width: 50%;

height: 18%;

transform:

rotate(-12deg);

transition:

transform

.55s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov:hover

.gennady-mic {

transform:

rotate(-3deg)

translateX(16%);

}

.gennady-mishakov .mic-body {

position: absolute;

left: 4%;

top: 47%;

width: 82%;

height:

clamp(

3px,

.35vw,

5px

);

border-radius: 999px;

background:

#222;

}

.gennady-mishakov .mic-head {

position: absolute;

right: 0;

top: 31%;

width: 27%;

aspect-ratio: 1.15;

border-radius: 50%;

background:

#111;

}

/* =========================================================

COUPLE

========================================================= */

.gennady-mishakov .couple {

position: absolute;

z-index: 14;

right: 20%;

bottom: 9%;

width: 30%;

height: 61%;

display: flex;

justify-content:

center;

align-items:

flex-end;

transition:

gap

.65s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov:hover

.couple {

gap: 0;

}

.gennady-mishakov .partner {

position: relative;

width: 45%;

height: 100%;

transition:

transform

.65s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov .groom {

transform:

translateX(-8%);

}

.gennady-mishakov .bride {

transform:

translateX(8%);

}

.gennady-mishakov:hover

.groom {

transform:

translateX(13%)

rotate(2deg);

}

.gennady-mishakov:hover

.bride {

transform:

translateX(-13%)

rotate(-2deg);

}

.gennady-mishakov .partner-head {

position: absolute;

left: 50%;

top: 7%;

width: 37%;

aspect-ratio: 1;

transform:

translateX(-50%);

border-radius: 50%;

background:

#cfab92;

}

.gennady-mishakov .partner-body {

position: absolute;

left: 50%;

bottom: 0;

width: 72%;

height: 68%;

transform:

translateX(-50%);

border-radius:

42%

42%

8%

8%;

}

.gennady-mishakov .groom

.partner-body {

background:

#2b2a2b;

}

.gennady-mishakov .bride

.partner-body {

background:

#f4f0e8;

box-shadow:

inset

0

0

0

1px

rgba(0,0,0,.05);

}

/* =========================================================

HEARTS

========================================================= */

.gennady-mishakov .hearts {

position: absolute;

z-index: 30;

left: 50%;

top: 10%;

transform:

translateX(-50%);

pointer-events: none;

}

.gennady-mishakov .hearts span {

position: absolute;

color:

rgba(159,55,52,.0);

font-size:

clamp(

7px,

.9vw,

13px

);

transform:

translateY(12px)

scale(.4);

transition:

color .4s ease,

transform

.8s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov .hearts span:nth-child(1) {

left: -18px;

transition-delay:

.05s;

}

.gennady-mishakov .hearts span:nth-child(2) {

left: 0;

top: -8px;

transition-delay:

.13s;

}

.gennady-mishakov .hearts span:nth-child(3) {

left: 17px;

top: 5px;

transition-delay:

.22s;

}

.gennady-mishakov:hover

.hearts span {

color:

rgba(159,55,52,.74);

transform:

translateY(-10px)

scale(1);

}

/* =========================================================

SPEECH

========================================================= */

.gennady-mishakov .speech-bubble {

position: absolute;

z-index: 25;

left: 10%;

top: 26%;

padding:

3%

4%;

border-radius:

clamp(

7px,

.9vw,

12px

);

background:

rgba(255,255,255,.88);

color:

rgba(0,0,0,.60);

font-size:

clamp(

4px,

.5vw,

7px

);

line-height: 1.35;

box-shadow:

0

10px

28px

rgba(0,0,0,.08);

opacity: .25;

transform:

translateY(7px)

scale(.96);

transition:

opacity .5s ease,

transform

.5s

cubic-bezier(.2,.8,.2,1);

}

.gennady-mishakov:hover

.speech-bubble {

opacity: 1;

transform:

translateY(0)

scale(1);

}

/* =========================================================

CONFETTI

========================================================= */

.gennady-mishakov .confetti {

position: absolute;

z-index: 40;

inset: 0;

opacity: 0;

pointer-events: none;

background-image:

radial-gradient(

circle,

rgba(153,70,62,.72) 0 2px,

transparent 2.5px

),

radial-gradient(

circle,

rgba(180,145,72,.72) 0 2px,

transparent 2.5px

),

radial-gradient(

circle,

rgba(80,104,114,.66) 0 2px,

transparent 2.5px

);

background-size:

43px 47px,

61px 53px,

71px 65px;

transition:

opacity

.25s

ease;

}

.gennady-mishakov .confetti-one {

background-position:

4px 1px,

17px 11px,

29px 21px;

}

.gennady-mishakov .confetti-two {

background-position:

17px 14px,

6px 24px,

38px 5px;

}

.gennady-mishakov .confetti-three {

background-position:

28px 31px,

37px 9px,

12px 36px;

}

.gennady-mishakov:hover

.confetti-one {

animation:

confettiFlash

.55s

ease

.30s

1;

}

.gennady-mishakov:hover

.confetti-two {

animation:

confettiFlash

.55s

ease

.80s

1;

}

.gennady-mishakov:hover

.confetti-three {

animation:

confettiFlash

.55s

ease

1.30s

1;

}

@keyframes confettiFlash {

0% {

opacity: 0;

transform:

translateY(-8%);

}

30% {

opacity: .9;

}

100% {

opacity: 0;

transform:

translateY(12%);

}

}

/* =========================================================

INTERACTIONS

========================================================= */

.gennady-mishakov .interactive-row {

position: absolute;

left: 5%;

right: 5%;

bottom: 7%;

display: grid;

grid-template-columns:

repeat(4,1fr);

gap: 1.5%;

}

.gennady-mishakov .interaction {

min-height:

clamp(

30px,

4.2vw,

56px

);

padding:

0

8%;

display: flex;

align-items: center;

gap: 10%;

border:

1px solid

rgba(0,0,0,.06);

border-radius:

clamp(

7px,

.9vw,

12px

);

background:

rgba(255,255,255,.50);

color:

rgba(0,0,0,.35);

font-size:

clamp(

3px,

.42vw,

6px

);

transition:

background .3s ease,

transform

.3s

cubic-bezier(.2,.8,.2,1),

color .3s ease;

}

.gennady-mishakov .interaction.active {

background: #111;

color: #fff;

}

.gennady-mishakov:hover

.interaction.active {

transform:

translateY(-2px);

}

.gennady-mishakov .interaction-icon {

width:

clamp(

15px,

1.8vw,

24px

);

aspect-ratio: 1;

display: grid;

place-items: center;

flex:

0

0

auto;

border-radius: 50%;

background:

rgba(0,0,0,.055);

font-size:

clamp(

5px,

.58vw,

8px

);

}

.gennady-mishakov .interaction.active

.interaction-icon {

background:

rgba(255,255,255,.12);

}

/* =========================================================

HINT

========================================================= */

.gennady-mishakov .stage-hint {

position: absolute;

z-index: 35;

left: 7%;

bottom: 22%;

color:

rgba(0,0,0,.24);

font-size:

clamp(

3px,

.37vw,

5px

);

transition:

opacity

.35s

ease;

}

.gennady-mishakov:hover

.stage-hint {

opacity: 0;

}

END_VISUAL_CSS

ENDPRODUCT

PRODUCT

id: course-lesson-template

Название: Шаблон уроков курса

Категория: Сервис

Порядок списка: 5

Главная: нет

NEW: да

Статус: в разработке

Коротко: Шаблон для оформления уроков курса на сайте из обычного конспекта или транскрибации.

Класс визуала: course-lessons

DESCRIPTION

Шаблон для учебных материалов на сайте. Я загружаю конспект или транскрибацию урока, а система превращает её в аккуратно оформленную страницу с заголовками, основными тезисами, примерами и переходом к следующему уроку. Идея в том, чтобы не верстать каждый урок вручную, а собирать весь курс в единой визуальной системе.

ENDDESCRIPTION

VISUAL_HTML

<div class="course-interface">

<div class="course-sidebar">

<div class="course-logo">

снимать<br>

красиво

</div>

<div class="course-progress">

<div class="progress-label">

КУРС

</div>

<div class="progress-count">

03 / 12

</div>

</div>

<div class="lesson-menu">

<div class="lesson-menu-item done">

<span class="lesson-number">

01

</span>

<span class="lesson-name">

введение

</span>

</div>

<div class="lesson-menu-item done">

<span class="lesson-number">

02

</span>

<span class="lesson-name">

крупности

</span>

</div>

<div class="lesson-menu-item active">

<span class="lesson-number">

03

</span>

<span class="lesson-name">

история

</span>

</div>

<div class="lesson-menu-item">

<span class="lesson-number">

04

</span>

<span class="lesson-name">

движение

</span>

</div>

</div>

</div>

<div class="lesson-page">

<div class="lesson-top">

<div class="lesson-kicker">

УРОК 03

</div>

<div class="lesson-time">

17:02

</div>

</div>

<div class="lesson-title">

Как видеть<br>

историю на съёмке

</div>

<div class="lesson-lead">

Большая история складывается из маленьких событий.

</div>

<div class="lesson-block">

<div class="block-number">

01

</div>

<div class="block-content">

<div class="block-title">

Где происходит событие?

</div>

<div class="block-lines">

<span></span>

<span></span>

<span></span>

</div>

</div>

</div>

<div class="lesson-block">

<div class="block-number">

02

</div>

<div class="block-content">

<div class="block-title">

Кто участвует?

</div>

<div class="block-lines">

<span></span>

<span></span>

</div>

</div>

</div>

<div class="lesson-example">

<div class="example-label">

ПРИМЕР

</div>

<div class="example-title">

ЗАГС

</div>

<div class="example-items">

<span>

общий план

</span>

<span>

пара

</span>

<span>

гости

</span>

<span>

кольца

</span>

</div>

</div>

<div class="next-lesson">

<span>

следующий урок

</span>

<strong>

движение камеры

</strong>

<span class="next-arrow">

</span>

</div>

</div>

</div>

END_VISUAL_HTML

VISUAL_CSS

.course-lessons {

background:

linear-gradient(

145deg,

#ecece8,

#d7d7d1

);

}

/* =========================================================

INTERFACE

========================================================= */

.course-lessons .course-interface {

position: absolute;

inset: 7%;

display: grid;

grid-template-columns:

28%

72%;

overflow: hidden;

border:

1px solid

rgba(0,0,0,.07);

border-radius:

clamp(

16px,

2vw,

28px

);

background:

#fff;

box-shadow:

0

32px

90px

rgba(0,0,0,.14);

transform:

perspective(1100px)

rotateX(.7deg)

rotateY(-1.3deg);

transition:

transform

.6s

cubic-bezier(.2,.8,.2,1),

box-shadow

.6s

cubic-bezier(.2,.8,.2,1);

}

.course-lessons:hover

.course-interface {

transform:

perspective(1100px)

rotateX(0deg)

rotateY(0deg);

box-shadow:

0

42px

110px

rgba(0,0,0,.18);

}

/* =========================================================

SIDEBAR

========================================================= */

.course-lessons .course-sidebar {

position: relative;

padding:

12%

11%;

overflow: hidden;

border-right:

1px solid

rgba(0,0,0,.065);

background:

#111;

}

.course-lessons .course-logo {

color: #fff;

font-size:

clamp(

12px,

1.7vw,

24px

);

line-height: .88;

font-weight: 720;

letter-spacing:

-.06em;

}

/* =========================================================

PROGRESS

========================================================= */

.course-lessons .course-progress {

margin-top: 24%;

padding-top: 14%;

display: flex;

align-items: center;

justify-content:

space-between;

border-top:

1px solid

rgba(255,255,255,.10);

}

.course-lessons .progress-label {

color:

rgba(255,255,255,.35);

font-size:

clamp(

3px,

.4vw,

6px

);

letter-spacing:

.14em;

}

.course-lessons .progress-count {

color:

rgba(255,255,255,.65);

font-size:

clamp(

4px,

.48vw,

7px

);

font-variant-numeric:

tabular-nums;

}

/* =========================================================

MENU

========================================================= */

.course-lessons .lesson-menu {

margin-top: 21%;

}

.course-lessons .lesson-menu-item {

min-height:

clamp(

31px,

4vw,

54px

);

padding:

0

6%;

display: grid;

grid-template-columns:

25px

1fr;

align-items: center;

gap: 8%;

border-bottom:

1px solid

rgba(255,255,255,.07);

color:

rgba(255,255,255,.31);

transition:

color

.3s

ease,

transform

.35s

cubic-bezier(.2,.8,.2,1);

}

.course-lessons .lesson-menu-item.done {

color:

rgba(255,255,255,.44);

}

.course-lessons .lesson-menu-item.active {

color: #fff;

}

.course-lessons:hover

.lesson-menu-item.active {

transform:

translateX(4px);

}

.course-lessons .lesson-number {

font-size:

clamp(

3px,

.4vw,

6px

);

font-variant-numeric:

tabular-nums;

}

.course-lessons .lesson-name {

font-size:

clamp(

4px,

.52vw,

7.5px

);

}

/* =========================================================

LESSON

========================================================= */

.course-lessons .lesson-page {

position: relative;

padding:

7%

8%;

overflow: hidden;

background:

#fafaf7;

}

/* =========================================================

TOP

========================================================= */

.course-lessons .lesson-top {

display: flex;

align-items: center;

justify-content:

space-between;

}

.course-lessons .lesson-kicker {

color:

rgba(0,0,0,.28);

font-size:

clamp(

3px,

.4vw,

6px

);

font-weight: 700;

letter-spacing:

.14em;

}

.course-lessons .lesson-time {

color:

rgba(0,0,0,.26);

font-size:

clamp(

3px,

.4vw,

6px

);

font-variant-numeric:

tabular-nums;

}

/* =========================================================

TITLE

========================================================= */

.course-lessons .lesson-title {

margin-top: 8%;

max-width: 70%;

color: #111;

font-size:

clamp(

17px,

2.5vw,

35px

);

line-height: .91;

font-weight: 690;

letter-spacing:

-.062em;

}

.course-lessons .lesson-lead {

max-width: 57%;

margin-top: 5%;

color:

rgba(0,0,0,.42);

font-size:

clamp(

4px,

.55vw,

8px

);

line-height: 1.45;

}

/* =========================================================

LESSON BLOCKS

========================================================= */

.course-lessons .lesson-block {

width: 58%;

margin-top: 7%;

padding:

5%

0;

display: grid;

grid-template-columns:

34px

1fr;

gap: 5%;

border-top:

1px solid

rgba(0,0,0,.07);

}

.course-lessons .block-number {

color:

rgba(0,0,0,.20);

font-size:

clamp(

4px,

.48vw,

7px

);

}

.course-lessons .block-title {

color:

rgba(0,0,0,.70);

font-size:

clamp(

5px,

.64vw,

9px

);

font-weight: 640;

}

.course-lessons .block-lines {

margin-top: 7%;

display: flex;

flex-direction: column;

gap:

clamp(

3px,

.35vw,

5px

);

}

.course-lessons .block-lines span {

width: 100%;

height:

clamp(

2px,

.28vw,

4px

);

border-radius: 999px;

background:

rgba(0,0,0,.07);

}

.course-lessons .block-lines span:nth-child(2) {

width: 82%;

}

.course-lessons .block-lines span:nth-child(3) {

width: 61%;

}

/* =========================================================

EXAMPLE

========================================================= */

.course-lessons .lesson-example {

position: absolute;

right: 7%;

top: 33%;

width: 28%;

min-height: 44%;

padding:

6%;

overflow: hidden;

border-radius:

clamp(

9px,

1.2vw,

16px

);

background:

#111;

box-shadow:

0

18px

45px

rgba(0,0,0,.14);

transition:

transform

.5s

cubic-bezier(.2,.8,.2,1),

box-shadow

.5s

ease;

}

.course-lessons:hover

.lesson-example {

transform:

translateY(-4px)

rotate(-1deg);

box-shadow:

0

24px

55px

rgba(0,0,0,.18);

}

.course-lessons .example-label {

color:

rgba(255,255,255,.35);

font-size:

clamp(

3px,

.36vw,

5px

);

font-weight: 700;

letter-spacing:

.14em;

}

.course-lessons .example-title {

margin-top: 17%;

color: #fff;

font-size:

clamp(

13px,

1.9vw,

27px

);

line-height: 1;

font-weight: 720;

letter-spacing:

-.055em;

}

.course-lessons .example-items {

margin-top: 19%;

display: flex;

flex-direction: column;

gap:

clamp(

7px,

.9vw,

12px

);

}

.course-lessons .example-items span {

min-height:

clamp(

20px,

2.6vw,

35px

);

padding:

0

9%;

display: flex;

align-items: center;

border:

1px solid

rgba(255,255,255,.10);

border-radius: 999px;

color:

rgba(255,255,255,.58);

font-size:

clamp(

3px,

.4vw,

6px

);

transition:

color

.3s

ease,

background

.3s

ease,

transform

.3s

cubic-bezier(.2,.8,.2,1);

}

.course-lessons:hover

.example-items span:nth-child(2) {

color: #fff;

background:

rgba(255,255,255,.08);

transform:

translateX(3px);

}

/* =========================================================

NEXT

========================================================= */

.course-lessons .next-lesson {

position: absolute;

left: 8%;

right: 8%;

bottom: 7%;

min-height:

clamp(

31px,

4vw,

54px

);

padding:

0

3%;

display: grid;

grid-template-columns:

auto

1fr

auto;

gap: 5%;

align-items: center;

border-top:

1px solid

rgba(0,0,0,.07);

border-bottom:

1px solid

rgba(0,0,0,.07);

color:

rgba(0,0,0,.30);

font-size:

clamp(

3px,

.4vw,

6px

);

}

.course-lessons .next-lesson strong {

color: #111;

font-size:

clamp(

4px,

.54vw,

8px

);

font-weight: 630;

text-align: right;

}

.course-lessons .next-arrow {

color: #111;

font-size:

clamp(

8px,

1vw,

14px

);

transition:

transform

.35s

cubic-bezier(.2,.8,.2,1);

}

.course-lessons:hover

.next-arrow {

transform:

translateX(4px);

}

/* =========================================================

LIGHT

========================================================= */

.course-lessons

.course-interface::after {

content: "";

position: absolute;

z-index: 50;

top: -80%;

left: -60%;

width: 22%;

height: 260%;

transform:

rotate(18deg);

background:

linear-gradient(

90deg,

transparent,

rgba(255,255,255,.24),

transparent

);

opacity: .28;

pointer-events: none;

transition:

left

1.2s

cubic-bezier(.2,.8,.2,1);

}

.course-lessons:hover

.course-interface::after {

left: 135%;

}

END_VISUAL_CSS

ENDPRODUCT