[html]
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<style>
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
background: transparent;
color: #222;
font-family: Arial, sans-serif;
}
body {
width: 100%;
overflow-x: hidden;
}
.profile-shop {
width: 100%;
color: #222;
}
.profile-shop__tabs {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 6px;
padding-top: 13px;
}
.profile-shop__tab {
display: block;
width: 98%;
padding: 10px 20px;
border: 0;
border-radius: 7px;
background: #ededed;
color: #222;
text-align: center;
cursor: pointer;
font: 500 13px Arial, sans-serif;
transition:
background-color .3s,
color .3s;
}
.profile-shop__tab:hover,
.profile-shop__tab.is-active {
background: #303030;
color: #ededed;
}
.profile-shop__windows {
position: relative;
overflow: hidden;
}
.profile-shop__window {
display: none;
padding: 21px 0 10px;
line-height: 1.5;
}
.profile-shop__window.is-active {
display: block;
animation: shopWindowShow .25s ease;
}
@keyframes shopWindowShow {
from {
opacity: 0;
transform: translateY(15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.profile-shop__title {
margin: 0 0 15px;
text-align: center;
font-family: Georgia, serif;
font-size: 22px;
font-style: italic;
}
.profile-shop__notice {
margin: 0 0 20px;
padding: 15px 18px;
border: 1px solid rgba(0, 0, 0, .13);
border-radius: 7px;
background: rgba(237, 237, 237, .7);
text-align: center;
font: 13px/1.6 Arial, sans-serif;
}
.profile-shop__notice p {
margin: 0 0 10px;
}
.profile-shop__notice p:last-child {
margin-bottom: 0;
}
.profile-shop__price-title {
margin: 20px 0 15px;
text-align: center;
font-family: Georgia, serif;
font-size: 17px;
font-style: italic;
}
.profile-shop__separator {
height: 1px;
margin: 28px 0;
border: 0;
background: rgba(0, 0, 0, .16);
}
.shop-gallery {
margin: 20px auto 25px;
}
.shop-item-wrap {
position: relative;
display: block;
margin: 0;
padding: 0;
line-height: 0;
}
.shop-selectable {
display: block;
margin: 0;
padding: 0;
cursor: pointer;
transition:
opacity .2s ease,
transform .2s ease,
outline-color .2s ease;
}
.shop-selectable:hover {
transform: translateY(-3px);
}
.shop-selectable.is-shop-selected {
opacity: .58;
outline: 3px solid #8b756b;
outline-offset: 3px;
}
.shop-item-wrap::after {
content: "✓";
position: absolute;
top: 7px;
right: 7px;
z-index: 3;
display: none;
align-items: center;
justify-content: center;
width: 25px;
height: 25px;
border-radius: 50%;
background: #303030;
color: #fff;
font: bold 15px/1 Arial, sans-serif;
pointer-events: none;
}
.shop-item-wrap.is-shop-selected::after {
display: flex;
}
.shop-gallery[data-shop-category="плашка"],
.shop-gallery[data-shop-category="фон"] {
display: grid;
grid-template-columns: repeat(8, 70px);
justify-content: center;
align-items: start;
gap: 10px;
width: min(100%, 630px);
}
.shop-gallery[data-shop-category="плашка"] > img,
.shop-gallery[data-shop-category="плашка"] > .shop-item-wrap,
.shop-gallery[data-shop-category="фон"] > img,
.shop-gallery[data-shop-category="фон"] > .shop-item-wrap {
width: 70px;
height: 200px;
}
.shop-gallery[data-shop-category="плашка"] img,
.shop-gallery[data-shop-category="фон"] img {
width: 70px !important;
min-width: 70px !important;
max-width: 70px !important;
height: 200px !important;
min-height: 200px !important;
max-height: 200px !important;
border: 0;
border-radius: 9px;
object-fit: cover;
object-position: center;
box-shadow: 0 2px 5px rgba(0, 0, 0, .25);
}
.profile-shop__custom {
margin: 18px 0 24px;
padding: 15px;
border: 1px solid rgba(0, 0, 0, .13);
border-radius: 7px;
background: rgba(255, 255, 255, .55);
}
.profile-shop__custom-title {
margin: 0 0 10px;
text-align: center;
font: 600 12px/1.5 Arial, sans-serif;
}
.profile-shop__custom-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 34px 34px;
gap: 6px;
margin-top: 7px;
}
.profile-shop__custom-row:first-child {
margin-top: 0;
}
.profile-shop__custom-input {
width: 100%;
min-width: 0;
height: 34px;
padding: 7px 10px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
outline: none;
background: rgba(255, 255, 255, .9);
color: #222;
font: 12px Arial, sans-serif;
}
.profile-shop__custom-input:focus {
border-color: rgba(48, 48, 48, .6);
}
.profile-shop__custom-control {
width: 34px;
height: 34px;
padding: 0;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
background: #ededed;
color: #222;
cursor: pointer;
font: 20px/1 Arial, sans-serif;
}
.profile-shop__custom-control:hover {
background: #303030;
color: #fff;
}
.profile-shop__custom-row:first-child [data-shop-custom-remove] {
visibility: hidden;
pointer-events: none;
}
.shop-gallery[data-shop-category="артефакт"] {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
justify-content: center;
gap: 14px;
}
.shop-gallery[data-shop-category="артефакт"] > img,
.shop-gallery[data-shop-category="артефакт"] > .shop-item-wrap {
width: auto;
max-width: 180px;
height: auto;
}
.shop-gallery[data-shop-category="артефакт"] img {
width: auto !important;
max-width: 180px !important;
height: auto !important;
max-height: 220px !important;
border: 0;
object-fit: contain;
}
.profile-shop__order {
margin-top: 25px;
padding: 18px;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 7px;
background: rgba(237, 237, 237, .75);
}
.profile-shop__order-head,
.profile-shop__order-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 15px;
}
.profile-shop__balance {
display: flex;
flex-wrap: wrap;
gap: 8px 22px;
margin: 0 0 12px;
padding: 10px 12px;
border: 1px solid rgba(0, 0, 0, .1);
border-radius: 5px;
background: rgba(255, 255, 255, .6);
font-size: 12px;
line-height: 1.5;
}
.profile-shop__balance span {
flex: 1 1 210px;
}
.profile-shop__balance b {
font-size: 13px;
}
.profile-shop__balance.is-negative [data-shop-profile-total] {
color: #a52a2a;
}
.profile-shop__order-head {
margin-bottom: 12px;
}
.profile-shop__order-head strong {
font-family: Georgia, serif;
font-size: 18px;
font-style: italic;
font-weight: normal;
}
.profile-shop__output {
display: block;
width: 100%;
min-height: 170px;
margin: 0 0 12px;
padding: 12px;
resize: vertical;
border: 1px solid rgba(0, 0, 0, .17);
border-radius: 5px;
outline: none;
background: rgba(255, 255, 255, .85);
color: #222;
font: 12px/1.6 Arial, sans-serif;
}
.profile-shop__order-footer {
flex-wrap: wrap;
font-size: 12px;
}
.profile-shop__buttons {
display: flex;
flex-wrap: wrap;
gap: 7px;
}
.profile-shop__button {
padding: 8px 13px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
background: rgba(255, 255, 255, .8);
color: #222;
cursor: pointer;
font: 12px Arial, sans-serif;
transition:
background-color .2s,
opacity .2s;
}
.profile-shop__button:hover:not(:disabled) {
background: #fff;
}
.profile-shop__button:disabled {
cursor: default;
opacity: .4;
}
.profile-shop__status {
min-height: 18px;
margin-top: 10px;
color: #555;
text-align: center;
font-size: 11px;
}
@media (max-width: 850px) {
.shop-gallery[data-shop-category="плашка"],
.shop-gallery[data-shop-category="фон"] {
grid-template-columns: repeat(8, 70px);
width: min(100%, 470px);
}
}
@media (max-width: 630px) {
.profile-shop__tabs {
grid-template-columns: repeat(2, 1fr);
}
.shop-gallery[data-shop-category="плашка"],
.shop-gallery[data-shop-category="фон"] {
grid-template-columns: repeat(4, 70px);
width: min(100%, 310px);
}
.profile-shop__order-head,
.profile-shop__order-footer {
align-items: stretch;
flex-direction: column;
}
.profile-shop__buttons {
width: 100%;
}
.profile-shop__button {
flex: 1 1 auto;
}
}
@media (max-width: 420px) {
.shop-gallery[data-shop-category="плашка"],
.shop-gallery[data-shop-category="фон"] {
grid-template-columns: repeat(3, 70px);
width: min(100%, 230px);
}
}
.quote-table-wrap {
text-align: center;
margin-bottom: 18px;
}
.quote-table {
display: inline-table;
width: 100%;
max-width: 450px;
text-align: left;
border-collapse: separate;
border-spacing: 0 10px;
background: rgba(255, 255, 255, .45);
border-radius: 8px;
}
.quote-table__label {
width: 28px;
padding: 6px 4px;
vertical-align: middle;
text-align: center;
color: #555;
border-right: 1px solid rgba(0, 0, 0, .1);
}
.quote-table__label span {
display: inline-block;
writing-mode: vertical-rl;
transform: rotate(180deg);
white-space: nowrap;
font: italic 700 12px / 1 var(--cursivef);
letter-spacing: .5px;
color: #303030;
}
.quote-table td {
padding: 4px 10px;
}
.quote-color-pair {
display: flex;
flex-wrap: wrap;
gap: 10px 14px;
}
.quote-color-pair__group {
display: flex;
align-items: center;
gap: 6px;
}
.quote-color-pair__tag {
font: 11px Arial, sans-serif;
color: #555;
}
.quote-color-row {
display: flex;
align-items: center;
gap: 8px;
}
.quote-color-picker {
width: 34px;
height: 34px;
padding: 0;
border: 1px solid rgba(0, 0, 0, .25);
border-radius: 6px;
cursor: pointer;
background: none;
}
.quote-color-hex {
width: 90px;
height: 34px;
padding: 0 8px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
outline: none;
background: rgba(255, 255, 255, .9);
color: #222;
font: 12px Arial, sans-serif;
text-align: center;
}
.quote-text-input--compact {
min-height: 34px;
padding: 6px 10px;
font-size: 11px;
}
.quote-mini-toggle {
display: inline-block;
margin-top: 6px;
padding: 5px 10px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 4px;
background: rgba(255, 255, 255, .8);
color: #222;
cursor: pointer;
font: 400 12px / 1 var(--sec-font);
}
.quote-mini-toggle.is-active {
background: #303030;
color: #fff;
}
.quote-combos {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin: 0 0 20px;
}
.quote-combo {
width: 90px;
padding: 8px;
border: 1px solid rgba(0, 0, 0, .18);
border-radius: 6px;
background: rgba(255, 255, 255, .6);
cursor: pointer;
text-align: center;
font: 11px Arial, sans-serif;
transition: outline-color .2s;
}
.quote-combo-swatch {
height: 30px;
margin-bottom: 6px;
border-radius: 4px;
}
.quote-combo.is-active {
outline: 2px solid #303030;
outline-offset: 2px;
}
.quote-combo-price {
display: block;
margin-top: 2px;
color: #555;
}
.quote-text-input {
display: block;
min-height: 60px;
padding: 10px 12px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 6px;
outline: none;
background: rgba(255, 255, 255, .9);
color: #222;
font: 12px/1.5 Arial, sans-serif;
text-align: left;
}
.quote-text-toggle {
display: block;
margin: 0 auto;
padding: 8px 16px;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: 5px;
background: rgba(255, 255, 255, .8);
color: #222;
cursor: pointer;
font: 12px Arial, sans-serif;
}
.quote-text-toggle.is-active {
background: #303030;
color: #fff;
}
</style>
<div class="profile-shop" id="profile-shop">
<div class="profile-shop__tabs">
<button class="profile-shop__tab is-active" type="button" data-shop-tab="bookmarks">
закладки
</button>
<button class="profile-shop__tab" type="button" data-shop-tab="backgrounds">
фоны
</button>
<button class="profile-shop__tab" type="button" data-shop-tab="artifacts">
артефакты
</button>
<button class="profile-shop__tab" type="button" data-shop-tab="quote">
плашка
</button>
</div>
<div class="profile-shop__windows">
<section class="profile-shop__window is-active" data-shop-window="bookmarks">
<h2 class="profile-shop__title">
закладки для профиля
</h2>
<div class="profile-shop__notice">
Закладка в профиль из нашей коллекции стоит
<strong>300 денег</strong>, закладка на ваш вкус —
<strong>550 денег</strong>.
Для обработки заявки оставьте ссылку на сообщение
в банке, где была оформлена покупка, а также ссылку
на желаемую закладку.
</div>
<div
class="profile-shop__custom"
data-shop-custom-group
data-shop-category="закладка на ваш вкус"
data-shop-price="550"
>
<div class="profile-shop__custom-title">
своя закладка — 550 денег
</div>
<div data-shop-custom-rows>
<div class="profile-shop__custom-row" data-shop-custom-row>
<input
class="profile-shop__custom-input"
type="text"
data-shop-custom-input
placeholder="вставьте ссылку на картинку"
>
<button class="profile-shop__custom-control" type="button" data-shop-custom-add title="Добавить ещё поле">+</button>
<button class="profile-shop__custom-control" type="button" data-shop-custom-remove title="Удалить поле">×</button>
</div>
</div>
</div>
<div
class="shop-gallery"
data-shop-category="плашка"
data-shop-price="300"
>
<img src="https://upforme.ru/uploads/001c/bd/d1/8/780175.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/866908.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/442819.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/286367.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/224561.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/988042.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/169463.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/18370.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/266460.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/840850.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/379600.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/415865.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/529814.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/826613.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/185620.png" alt="Закладка">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/45725.png" alt="Закладка">
</div>
</section>
<section class="profile-shop__window" data-shop-window="backgrounds">
<h2 class="profile-shop__title">
фоны для личной странички
</h2>
<div class="profile-shop__notice">
<p>
Фоны личной страницы из нашей коллекции стоят
<strong>250 денег</strong>, из ваших исходников —
<strong>350 денег</strong>.
</p>
<p>
После покупки оформите заявку и приложите ссылку
на выбранный фон.
</p>
<p>
<strong><em>Примечание:</em></strong>
при открытии личной страницы фон будет виден
в полном размере. Перед покупкой рекомендуется
открыть изображение в новой вкладке.
</p>
</div>
<div
class="profile-shop__custom"
data-shop-custom-group
data-shop-category="фон из ваших исходников"
data-shop-price="350"
>
<div class="profile-shop__custom-title">
свой фон — 350 денег
</div>
<div data-shop-custom-rows>
<div class="profile-shop__custom-row" data-shop-custom-row>
<input
class="profile-shop__custom-input"
type="text"
data-shop-custom-input
placeholder="вставьте ссылку на картинку"
>
<button class="profile-shop__custom-control" type="button" data-shop-custom-add title="Добавить ещё поле">+</button>
<button class="profile-shop__custom-control" type="button" data-shop-custom-remove title="Удалить поле">×</button>
</div>
</div>
</div>
<div
class="shop-gallery"
data-shop-category="фон"
data-shop-price="250"
>
<img src="https://upforme.ru/uploads/001c/bd/d1/8/302052.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/291726.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/985217.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/12909.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/646367.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/309066.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/554289.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/450484.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/845421.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/361653.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/720949.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/283145.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/331964.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/898671.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/250341.png" alt="Фон">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/526811.png" alt="Фон">
</div>
</section>
<section class="profile-shop__window" data-shop-window="artifacts">
<h2 class="profile-shop__title">
одноразовые артефакты
</h2>
<div class="profile-shop__notice">
Сгорает после использования. В одном квесте можно
использовать <strong>до трёх</strong> разовых
предметов. Применяются как до, так и после броска.
</div>
<div class="profile-shop__price-title">
цена: 300 денег
</div>
<div
class="shop-gallery"
data-shop-category="артефакт"
data-shop-price="300"
>
<img src="https://upforme.ru/uploads/001c/bd/d1/8/821120.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/271525.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/64/39096.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/64/856065.png" alt="Артефакт">
</div>
<div class="profile-shop__price-title">
цена: 400 денег
</div>
<div
class="shop-gallery"
data-shop-category="артефакт"
data-shop-price="400"
>
<img src="https://upforme.ru/uploads/001c/bd/d1/64/199670.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/8/54236.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/64/795532.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/4/667715.png" alt="Артефакт">
</div>
<hr class="profile-shop__separator">
<h2 class="profile-shop__title">
многоразовые артефакты
</h2>
<div class="profile-shop__notice">
Действует <strong>в течение одного квеста</strong>,
после чего сгорает. При себе можно иметь
<strong>только один</strong>. Менять артефакт
во время игры нельзя.
</div>
<div class="profile-shop__price-title">
цена: 500 денег
</div>
<div
class="shop-gallery"
data-shop-category="артефакт"
data-shop-price="500"
>
<img src="https://upforme.ru/uploads/001c/bd/d1/8/255932.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/4/746461.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/64/171210.png" alt="Артефакт">
<img src="https://upforme.ru/uploads/001c/bd/d1/64/168079.png" alt="Артефакт">
</div>
</section>
<section class="profile-shop__window" data-shop-window="quote">
<h2 class="profile-shop__title">
плашка
</h2>
<div class="profile-shop__notice">
Всё ниже — бесплатный предпросмотр, результат сразу виден
в карточке автора темы слева. Купить можно готовую комбинацию
цвета (<strong>350</strong>) и/или свой текст (<strong>200</strong>).
Лз сохраняется в заявку бесплатно.
</div>
<div class="quote-table-wrap">
<table class="quote-table">
<tr>
<td class="quote-table__label"><span>лз</span></td>
<td>
<div
class="quote-text-input quote-text-input--compact"
contenteditable="true"
data-lz-input
data-placeholder="HTML-код лз"
></div>
<button class="quote-mini-toggle" type="button" data-lz-toggle>
сохранить в заявку
</button>
</td>
</tr>
<tr>
<td class="quote-table__label"><span>плашка</span></td>
<td>
<div
class="quote-text-input quote-text-input--compact"
contenteditable="true"
data-quote-text-input
data-placeholder="свой текст для предпросмотра"
></div>
<button class="quote-mini-toggle" type="button" data-quote-text-toggle>
заказать — 200 денег
</button>
</td>
</tr>
<tr>
<td class="quote-table__label"><span>цвет</span></td>
<td>
<div class="quote-color-pair">
<span class="quote-color-pair__group">
<span class="quote-color-pair__tag">фон</span>
<input class="quote-color-picker" type="color" data-quote-picker-bg value="#2b2b33">
<input class="quote-color-hex" type="text" data-quote-hex-bg placeholder="#2b2b33" maxlength="7">
</span>
<span class="quote-color-pair__group">
<span class="quote-color-pair__tag">текст</span>
<input class="quote-color-picker" type="color" data-quote-picker-color value="#d8c9a3">
<input class="quote-color-hex" type="text" data-quote-hex-color placeholder="#d8c9a3" maxlength="7">
</span>
</div>
</td>
</tr>
</table>
</div>
<div class="profile-shop__price-title">
готовые комбинации — 350 денег
</div>
<div class="quote-combos">
<div class="quote-combo" data-quote-combo="combo1">
<div class="quote-combo-swatch" style="background:#2b2b33"></div>
Полночь
<span class="quote-combo-price">350</span>
</div>
<div class="quote-combo" data-quote-combo="combo2">
<div class="quote-combo-swatch" style="background:#3a2a2f"></div>
Пепел розы
<span class="quote-combo-price">350</span>
</div>
<div class="quote-combo" data-quote-combo="combo3">
<div class="quote-combo-swatch" style="background:#2c332b"></div>
Мох
<span class="quote-combo-price">350</span>
</div>
<div class="quote-combo" data-quote-combo="combo4">
<div class="quote-combo-swatch" style="background:#3a2a1c"></div>
Ржавчина
<span class="quote-combo-price">350</span>
</div>
<div class="quote-combo" data-quote-combo="combo5">
<div class="quote-combo-swatch" style="background:#2c2f36"></div>
Туман
<span class="quote-combo-price">350</span>
</div>
</div>
</section>
</div>
<div class="profile-shop__order">
<div class="profile-shop__order-head">
<strong>ваша покупка</strong>
<span>
выбрано:
<b data-shop-count>0</b>
</span>
</div>
<textarea
class="profile-shop__output"
data-shop-output
readonly
placeholder="нажмите на картинку или вставьте свою ссылку"
></textarea>
<div class="profile-shop__balance" data-shop-balance>
<span>
банк:
<b data-shop-bank>загрузка…</b>
денег
</span>
<span>
общая сумма на профиле:
<b data-shop-profile-total>—</b>
</span>
</div>
<div class="profile-shop__order-footer">
<span>
общая сумма покупки:
<b data-shop-total>0</b>
денег
</span>
<div class="profile-shop__buttons">
<button
class="profile-shop__button"
type="button"
data-shop-copy
disabled
>
скопировать
</button>
<button
class="profile-shop__button"
type="button"
data-shop-clear
disabled
>
очистить
</button>
</div>
</div>
<div class="profile-shop__status" data-shop-status></div>
</div>
</div>
<script>
(function ($) {
$(function () {
var CHANNEL = 'broken-geis-profile-shop-v4';
var QUOTE_FIELD_ID = 5;
var COMBOS = [
{ id: 'combo1', title: 'Полночь', bg: '#2b2b33', text: '#d8c9a3', defaultQuote: 'тишина здесь гуще, чем где-либо ещё' },
{ id: 'combo2', title: 'Пепел розы', bg: '#3a2a2f', text: '#e3b7b0', defaultQuote: 'то, что сгорело, ещё помнит свою форму' },
{ id: 'combo3', title: 'Мох', bg: '#2c332b', text: '#c7d2b8', defaultQuote: 'здесь время растёт медленнее' },
{ id: 'combo4', title: 'Ржавчина', bg: '#3a2a1c', text: '#d9a468', defaultQuote: 'старое железо хранит все клятвы' },
{ id: 'combo5', title: 'Туман', bg: '#2c2f36', text: '#b8c4cf', defaultQuote: 'дорога есть, пока её не видно' }
];
var $shop = $('#profile-shop');
var selected = {};
var bank = null;
var bankLoaded = false;
var quoteState = {
comboId: null,
customText: null,
defaultText: '',
wantsCustomText: false,
previewBg: null,
previewColor: null
};
var lzState = {
html: null,
defaultHtml: '',
wantsSave: false
};
var $output = $shop.find('[data-shop-output]');
var $count = $shop.find('[data-shop-count]');
var $total = $shop.find('[data-shop-total]');
var $bank = $shop.find('[data-shop-bank]');
var $profileTotal = $shop.find('[data-shop-profile-total]');
var $balance = $shop.find('[data-shop-balance]');
var $copy = $shop.find('[data-shop-copy]');
var $clear = $shop.find('[data-shop-clear]');
var $status = $shop.find('[data-shop-status]');
$shop.on('click', '[data-shop-tab]', function () {
var tab = $(this).attr('data-shop-tab');
$shop.find('[data-shop-tab]').removeClass('is-active');
$(this).addClass('is-active');
$shop.find('[data-shop-window]').removeClass('is-active');
$shop.find('[data-shop-window="' + tab + '"]').addClass('is-active');
});
$shop.find('.shop-gallery').each(function () {
var $gallery = $(this);
var category = $gallery.attr('data-shop-category');
var price = +$gallery.attr('data-shop-price');
$gallery.find('img').each(function () {
$(this)
.attr('data-shop-category', category)
.attr('data-shop-price', price)
.addClass('shop-selectable')
.wrap('<span class="shop-item-wrap"></span>');
});
});
function getCombo(id) {
var i;
for (i = 0; i < COMBOS.length; i++) {
if (COMBOS[i].id === id) {
return COMBOS[i];
}
}
return null;
}
function getItems() {
var items = Object.keys(selected).map(function (key) {
return selected[key];
});
$shop.find('[data-shop-custom-group]').each(function () {
var category = $(this).attr('data-shop-category');
var price = +$(this).attr('data-shop-price');
$(this).find('[data-shop-custom-input]').each(function () {
var url = $.trim($(this).val());
if (url) {
items.push({ url: url, category: category, price: price });
}
});
});
if (quoteState.comboId) {
var combo = getCombo(quoteState.comboId);
if (combo) {
items.push({
url: 'комбинация «' + combo.title + '» (фон ' + combo.bg + ', цвет текста ' + combo.text +
', текст плашки: ' + combo.defaultQuote + ')',
category: 'готовая комбинация плашки',
price: 350
});
}
}
if (quoteState.wantsCustomText && quoteState.customText) {
items.push({
url: 'текст: «' + quoteState.customText + '»',
category: 'свой текст на плашке',
price: 200
});
}
if (lzState.wantsSave && lzState.html) {
items.push({
url: 'лз: ' + lzState.html,
category: 'личное звание (лз)',
price: 0
});
}
return items;
}
function getTotal(items) {
var total = 0;
$.each(items, function (_, item) {
total += item.price;
});
return total;
}
function buildMessage(items, total) {
if (!items.length) return '';
var lines = [];
var prices = [];
$.each(items, function (i, item) {
lines.push((i + 1) + '. ' + item.url + ' | ' + item.category);
prices.push(item.price);
});
lines.push('');
lines.push('Общая сумма покупки: ' + prices.join(' + ') + ' = ' + total + ' денег');
if (bankLoaded && bank !== null) {
lines.push('');
lines.push('Банк: ' + bank + ' денег');
lines.push('Общая сумма на профиле: ' + bank + ' - ' + total + ' = ' + (bank - total) + ' денег');
}
return lines.join('\n');
}
function render() {
var items = getItems();
var total = getTotal(items);
var hasItems = items.length > 0;
$count.text(items.length);
$total.text(total);
$output.val(buildMessage(items, total));
$copy.prop('disabled', !hasItems);
$clear.prop('disabled', !hasItems);
if (!bankLoaded) {
$bank.text('загрузка…');
$profileTotal.text('—');
} else if (bank === null) {
$bank.text('не найден');
$profileTotal.text('—');
} else {
$bank.text(bank);
$profileTotal.text(bank + ' - ' + total + ' = ' + (bank - total) + ' денег');
}
$balance.toggleClass('is-negative', bank !== null && bank - total < 0);
}
function buildBookmarkHtml(imageUrl) {
return '<div class="perspage1"><a href="#" onclick="return false;">' +
'<img src="' + imageUrl + '" title="личная страница"></a></div>';
}
function sendPreviewUpdate(partial) {
var payload = $.extend({}, partial);
window.parent.postMessage({
channel: CHANNEL,
type: 'profile-shop-preview-update',
value: payload
}, '*');
}
$shop.on('click', '.shop-selectable', function (e) {
e.preventDefault();
var $image = $(this);
var url = $image.attr('src');
var category = $image.attr('data-shop-category');
var key = category + '|' + url;
var $wrap = $image.parent();
var wasSelected = !!selected[key];
if (category === 'плашка' && !wasSelected) {
Object.keys(selected).forEach(function (k) {
if (selected[k].category === 'плашка' && k !== key) {
delete selected[k];
}
});
$shop.find('.shop-gallery[data-shop-category="плашка"] .shop-selectable').each(function () {
if (this !== $image[0]) {
$(this).add($(this).parent()).removeClass('is-shop-selected');
}
});
}
if (wasSelected) {
delete selected[key];
$image.add($wrap).removeClass('is-shop-selected');
} else {
selected[key] = {
url: url,
category: category,
price: +$image.attr('data-shop-price')
};
$image.add($wrap).addClass('is-shop-selected');
}
if (category === 'плашка') {
sendPreviewUpdate({ bookmarkHtml: wasSelected ? null : buildBookmarkHtml(url) });
}
render();
});
$shop.on('click', '[data-shop-custom-add]', function () {
var $row = $(this).closest('[data-shop-custom-row]').clone();
$row.find('input').val('');
$(this).closest('[data-shop-custom-rows]').append($row);
$row.find('input').focus();
render();
});
$shop.on('click', '[data-shop-custom-remove]', function () {
$(this).closest('[data-shop-custom-row]').remove();
render();
});
$shop.on('input', '[data-shop-custom-input]', render);
$copy.on('click', function () {
var text = $output.val();
function fallbackCopy() {
$output[0].select();
try {
document.execCommand('copy');
$status.text('Сообщение скопировано.');
} catch (err) {
$status.text('Не удалось скопировать — выделите текст вручную.');
}
setTimeout(function () { $status.text(''); }, 2000);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
$status.text('Сообщение скопировано.');
setTimeout(function () { $status.text(''); }, 2000);
}, fallbackCopy);
} else {
fallbackCopy();
}
});
$clear.on('click', function () {
selected = {};
$shop.find('.is-shop-selected').removeClass('is-shop-selected');
$shop.find('[data-shop-custom-group]').each(function () {
var $rows = $(this).find('[data-shop-custom-row]');
$rows.first().find('input').val('');
$rows.slice(1).remove();
});
quoteState.comboId = null;
quoteState.wantsCustomText = false;
$shop.find('[data-quote-combo]').removeClass('is-active');
$shop.find('[data-quote-text-toggle]')
.removeClass('is-active')
.text('заказать — 200 денег');
lzState.wantsSave = false;
$shop.find('[data-lz-toggle]')
.removeClass('is-active')
.text('сохранить лз в заявку');
render();
});
var HEX_RE = /^#[0-9a-fA-F]{6}$/;
function applyCustomBg(hex) {
if (!HEX_RE.test(hex)) return;
quoteState.previewBg = hex;
$shop.find('[data-quote-combo]').removeClass('is-active');
quoteState.comboId = null;
$shop.find('[data-quote-picker-bg]').val(hex);
$shop.find('[data-quote-hex-bg]').val(hex);
sendPreviewUpdate({ quoteBg: hex });
render();
}
function applyCustomColor(hex) {
if (!HEX_RE.test(hex)) return;
quoteState.previewColor = hex;
$shop.find('[data-quote-combo]').removeClass('is-active');
quoteState.comboId = null;
$shop.find('[data-quote-picker-color]').val(hex);
$shop.find('[data-quote-hex-color]').val(hex);
sendPreviewUpdate({ quoteColor: hex });
render();
}
$shop.on('input change', '[data-quote-picker-bg]', function () {
applyCustomBg($(this).val());
});
$shop.on('input', '[data-quote-hex-bg]', function () {
var hex = $.trim($(this).val());
if (hex && hex.charAt(0) !== '#') hex = '#' + hex;
if (HEX_RE.test(hex)) applyCustomBg(hex);
});
$shop.on('input change', '[data-quote-picker-color]', function () {
applyCustomColor($(this).val());
});
$shop.on('input', '[data-quote-hex-color]', function () {
var hex = $.trim($(this).val());
if (hex && hex.charAt(0) !== '#') hex = '#' + hex;
if (HEX_RE.test(hex)) applyCustomColor(hex);
});
$shop.on('click', '[data-quote-combo]', function () {
var id = $(this).attr('data-quote-combo');
var combo = getCombo(id);
if (!combo) return;
var wasActive = $(this).hasClass('is-active');
$shop.find('[data-quote-combo]').removeClass('is-active');
if (wasActive) {
quoteState.comboId = null;
quoteState.previewBg = null;
quoteState.previewColor = null;
sendPreviewUpdate({ quoteBg: null, quoteColor: null, quoteText: null });
} else {
$(this).addClass('is-active');
quoteState.comboId = id;
quoteState.previewBg = combo.bg;
quoteState.previewColor = combo.text;
$shop.find('[data-quote-picker-bg]').val(combo.bg);
$shop.find('[data-quote-hex-bg]').val(combo.bg);
$shop.find('[data-quote-picker-color]').val(combo.text);
$shop.find('[data-quote-hex-color]').val(combo.text);
sendPreviewUpdate({
quoteBg: quoteState.previewBg,
quoteColor: quoteState.previewColor,
quoteText: combo.defaultQuote
});
}
render();
});
function sanitizeToTextWithBr(rawHtml) {
var html = String(rawHtml);
html = html.replace(/<div><br\s*\/?><\/div>/gi, '<br>');
html = html.replace(/<\/div>\s*<div>/gi, '<br>');
html = html.replace(/<\/?div[^>]*>/gi, '');
html = html.replace(/<br\s*\/?>/gi, '<br>');
html = html.replace(/<(?!br\s*\/?>)[^>]+>/gi, '');
return html;
}
$shop.on('keydown', '[data-quote-text-input]', function (e) {
if (e.key === 'Enter' || e.keyCode === 13) {
e.preventDefault();
document.execCommand('insertLineBreak');
}
});
$shop.on('input', '[data-quote-text-input]', function () {
var clean = sanitizeToTextWithBr($(this).html());
quoteState.customText = clean;
sendPreviewUpdate({ quoteText: clean });
});
$shop.on('click', '[data-quote-text-toggle]', function () {
quoteState.wantsCustomText = !quoteState.wantsCustomText;
$(this).toggleClass('is-active', quoteState.wantsCustomText);
$(this).text(quoteState.wantsCustomText
? 'добавлено ✓'
: 'заказать — 200 денег');
render();
});
var $lzInput = $shop.find('[data-lz-input]');
function sanitizeLzHtml(rawHtml) {
var html = String(rawHtml);
html = html.replace(/<script[\s\S]*?<\/script>/gi, '');
html = html.replace(/<iframe[\s\S]*?<\/iframe>/gi, '');
html = html.replace(/ on\w+\s*=\s*"[^"]*"/gi, '');
html = html.replace(/ on\w+\s*=\s*'[^']*'/gi, '');
html = html.replace(/javascript\s*:/gi, '');
return html;
}
function applyLzValue(rawText) {
var clean = sanitizeLzHtml(rawText);
lzState.html = clean;
sendPreviewUpdate({ fld1Html: clean });
}
$shop.on('input', '[data-lz-input]', function () {
applyLzValue($(this).text());
});
$shop.on('paste', '[data-lz-input]', function (e) {
var clipboard = (e.originalEvent || e).clipboardData || window.clipboardData;
if (!clipboard) return;
e.preventDefault();
var text = clipboard.getData('text/plain') || clipboard.getData('text');
document.execCommand('insertText', false, text);
});
$shop.on('click', '[data-lz-toggle]', function () {
lzState.wantsSave = !lzState.wantsSave;
$(this).toggleClass('is-active', lzState.wantsSave);
$(this).text(lzState.wantsSave
? 'сохранено ✓'
: 'сохранить в заявку');
render();
});
window.addEventListener('message', function (e) {
if (!e.data || e.data.channel !== CHANNEL) return;
if (e.data.type === 'profile-shop-bank-value') {
bankLoaded = true;
bank = parseInt(e.data.value, 10);
if (isNaN(bank)) bank = null;
render();
return;
}
if (e.data.type === 'profile-shop-viewer-value' && e.data.ready) {
viewerReady = true;
var profile = e.data.value || {};
quoteState.defaultText = profile.quote || '';
}
});
var bankRequestTimer = null;
function requestBank() {
window.parent.postMessage({
channel: CHANNEL,
type: 'profile-shop-bank-request'
}, '*');
}
function startBankRequest() {
requestBank();
bankRequestTimer = setInterval(function () {
if (bankLoaded) {
clearInterval(bankRequestTimer);
bankRequestTimer = null;
return;
}
requestBank();
}, 1000);
}
var viewerRequestTimer = null;
var viewerReady = false;
function requestViewerProfile() {
window.parent.postMessage({
channel: CHANNEL,
type: 'profile-shop-viewer-request'
}, '*');
}
function startViewerRequest() {
requestViewerProfile();
viewerRequestTimer = setInterval(function () {
if (viewerReady) {
clearInterval(viewerRequestTimer);
viewerRequestTimer = null;
return;
}
requestViewerProfile();
}, 1000);
}
render();
startBankRequest();
startViewerRequest();
});
})(jQuery);
</script>
[/html]















