From 17ac4e94d72ab1193ed82f6583701eae44d9c089 Mon Sep 17 00:00:00 2001 From: Miwory Date: Sat, 30 Aug 2025 04:31:43 +0300 Subject: [PATCH] k1r4ka chat gen 1 --- .../k1r4ka/generation 1/index.html | 25 + StreamLabsChats/k1r4ka/generation 1/script.js | 535 ++++++++++++++++++ StreamLabsChats/k1r4ka/generation 1/style.css | 310 ++++++++++ 3 files changed, 870 insertions(+) create mode 100644 StreamLabsChats/k1r4ka/generation 1/index.html create mode 100644 StreamLabsChats/k1r4ka/generation 1/script.js create mode 100644 StreamLabsChats/k1r4ka/generation 1/style.css diff --git a/StreamLabsChats/k1r4ka/generation 1/index.html b/StreamLabsChats/k1r4ka/generation 1/index.html new file mode 100644 index 0000000..073c7f6 --- /dev/null +++ b/StreamLabsChats/k1r4ka/generation 1/index.html @@ -0,0 +1,25 @@ +
+ 1 +
+ + + + diff --git a/StreamLabsChats/k1r4ka/generation 1/script.js b/StreamLabsChats/k1r4ka/generation 1/script.js new file mode 100644 index 0000000..4f6c444 --- /dev/null +++ b/StreamLabsChats/k1r4ka/generation 1/script.js @@ -0,0 +1,535 @@ +let $chatBox = $(".sl__chat__layout"); + +let usersPfp = {}; +let parity = true; + +let emoteSetId; +let websocketEmotesConnected = false; +let globalEmotes = []; +let channelEmotes = []; +let subMysteries = []; + +let messageProcessingList = [ + detachMessage, + loadGlobalEmotes, + loadChannelEmotes, + processTags, + getProfilePicture, + cleanText, + userPings, + upscaleBadges, + upscaleEmotes, + process7TVEmotes, + fixEmotesPadding, + largeEmotes, + parityParse, + preloadImages, + animate, +]; + +$(document).on("onEventReceived", function (event) { + let details = event.detail; + let command = details.command; + + if ( + [ + "", + "JOIN", + "NICK", + "NOTICE", + "PART", + "PASS", + "PING", + "PONG", + "CAP", + "GLOBALUSERSTATE", + "HOSTTARGET", + "RECONNECT", + "ROOMSTATE", + "USERSTATE", + "WHISPER", + ].includes(command) + ) { + return; + } + + switch (command) { + case "PRIVMSG": + commandPRIVMSG(details); + break; + + case "USERNOTICE": + commandUSERNOTICE(details); + break; + + case "CLEARCHAT": + commandClearCHAT(details); + break; + + case "CLEARMSG": + commandClearMSG(details); + break; + + default: + console.log(`Event ${command} not handled.`, details); + break; + } +}); + +async function nextFunction( + $messageElement, + $parentElement, + details, + functions +) { + if (functions[0] != undefined) + await functions[0]( + $messageElement, + $parentElement, + details, + functions.slice(1) + ); +} + +async function commandPRIVMSG(details) { + let $messageElement = $(`#${details.messageId}`); + let $parentElement = $messageElement.parent() || $chatBox; + + if (details.body == '!event' && details.tags['user-id'] == details.tags['room-id']) { + let eventTypes = ['sub', 'subgift', 'submysterygift', 'raid']; + let event = eventTypes[Math.floor(Math.random()*eventTypes.length)]; + details.tags['msg-id'] = event; + return commandUSERNOTICE(details); + } + + if (!$messageElement.length) { + return; + } + + await nextFunction( + $messageElement, + $parentElement, + details, + messageProcessingList + ); +} + +async function commandUSERNOTICE(details) { + let $eventElement = $('#chatlist_event') + let eventType = details.tags['msg-id'] + let author = details.tags['display-name'] + let tier; + let content; + let desc; + let type; + + let displayName = details.tags['display-name'] + let recipient = details.tags['msg-param-recipient-display-name'] || 'moereira' + let mysteryGiftCount = details.tags['msg-param-mass-gift-count'] || 100 + let viewerCount = details.tags['msg-param-viewerCount'] || 100 + let subPlan = details.tags['msg-param-sub-plan'] || 1000 + + switch (subPlan) { + case 1000: + tier = '1'; + break; + + case 2000: + tier = '2'; + break; + + case 3000: + tier = '3'; + break; + + default: + break; + } + + if (!$eventElement.length) { + return + } + + switch (eventType) { + case 'sub': + case 'resub': + case 'standardpayforward': + case 'communitypayforward': + case 'giftpaidupgrade': + case 'primepaidupgrade': + content = 'subscribed' + type = 'sub'; + desc = `with tier ${tier}` + break; + case 'subgift': + case 'anonsubgift': + if (subMysteries.includes(details.tags['msg-param-origin-id'])) return + content = `Has gifted a sub to`; + desc = recipient; + type = 'gift'; + break; + case 'submysterygift': + if (subMysteries.includes(details.tags['msg-param-origin-id'])) return + content = `Has gifted`; + desc = `${mysteryGiftCount} subs`; + type = 'gift'; + break; + case 'raid': + content = `Has raided`; + desc = `with ${viewerCount} viewers`; + type = 'raid'; + break; + default: + return; + } + + $eventElement = $eventElement.html() + $eventElement = $eventElement.replace('{messageId}', details.messageId) + $eventElement = $eventElement.replace('{author}', author) + $eventElement = $eventElement.replace('{content}', content) + $eventElement = $eventElement.replace('{desc}', desc) + $eventElement = $($eventElement) + + $eventElement.addClass(type) + $eventElement.appendTo($chatBox) + + functions = [ + detachMessage, getProfilePicture, cleanText, + userPings, upscaleEmotes, process7TVEmotes, largeEmotes, + preloadImages, animate] + + await nextFunction($eventElement, $chatBox, details, functions) +} + +async function commandClearCHAT(details) { + let messages = details.body + ? $(`[userId="${details.tags["target-user-id"]}"]`) + : $("message"); + for (let i = 0; i < messages.length; i++) { + const message = messages.eq(i); + setTimeout(() => { + message.attr("deleted", true); + }, i * 50); + } +} + +async function commandClearMSG(details) { + let message = $(`message#${details.messageId}`); + message.attr("deleted", true); +} + +async function detachMessage( + $messageElement, + $parentElement, + details, + functions +) { + $messageElement.detach(); + $messageElement.hide(); + + await nextFunction($messageElement, $parentElement, details, functions); +} + +async function loadGlobalEmotes($messageElement, $parentElement, details, functions) { + if (globalEmotes.length == 0) { + fetch('https://7tv.io/v3/emote-sets/global') + .then(response => { + if (!response.ok) { + throw new Error(`Global emotes: Error: (${response.status})`); + } + return response.json(); + }) + .then(data => { + console.log(`Global emotes: Success (${data.emotes.length})`); + globalEmotes = data.emotes; + }) + .catch(error => { + console.log(error.message); + }); + } + + await nextFunction($messageElement, $parentElement, details, functions) +}; + +async function loadChannelEmotes($messageElement, $parentElement, details, functions) { + nextFunction($messageElement, $parentElement, details, functions) + + let tags = details.tags; + let roomId = tags['room-id']; + + if (!emoteSetId) { + try { + let response = await fetch(`https://7tv.io/v3/users/twitch/${roomId}`); + if (!response.ok) { + throw new Error(`Channel emotes: Error: (${response.status})`); + } + let data = await response.json(); + console.log(`Channel emotes: Success (${data.emote_set.emotes.length})`); + channelEmotes = data.emote_set.emotes; + emoteSetId = data.emote_set.id; + } catch (error) { + console.log(error.message); + return + } + } + + if (!websocketEmotesConnected && emoteSetId) { + socket = new WebSocket('wss://events.7tv.io/v3'); + websocketEmotesConnected = true; + + socket.onopen = function (event) { + console.log('Connected to 7TV WebSocket'); + socket.send(JSON.stringify({ + 'op': 35, + 'd': { + 'type': 'emote_set.update', + 'condition': { + 'object_id': emoteSetId + } + } + })); + }; + + socket.onmessage = function (event) { + let data = JSON.parse(event.data); + + switch (data.op) { + case 0: + let eventData = data.d.body; + + if (eventData.hasOwnProperty('pulled')) { + let emoteId = eventData.pulled[0].old_value.id; + channelEmotes = channelEmotes.filter(obj => + obj.id !== emoteId); + }; + if (eventData.hasOwnProperty('pushed')) { + let emoteData = eventData.pushed[0].value; + channelEmotes.push(emoteData); + }; + if (eventData.hasOwnProperty('updated')) { + let emoteId = eventData.updated[0].old_value.id; + let emoteData = eventData.updated[0].value; + + let emoteIndex = channelEmotes.findIndex( + obj => obj.id === emoteId); + + if (emoteIndex !== -1) { + channelEmotes[emoteIndex] = emoteData; + }; + }; + + break; + case 4: + socket.close(); + websocketEmotesConnected = false; + break; + }; + }; + + socket.onerror = function (error) { + console.error('WebSocket error:', error); + }; + + socket.onclose = function (event) { + console.log('WebSocket closed:', event.code, event.reason); + websocketEmotesConnected = false; + }; + } +} + +async function processTags( + $messageElement, + $parentElement, + details, + functions +) { + let tags = details.tags; + let info = tags["badge-info"]; + let badges = tags.badges.split(","); + let msgId = tags["msg-id"]; + + if (info) { + let badge = info.replace("/", "-"); + $messageElement.addClass(badge); + } + + badges.forEach((badge) => { + let name = badge.split("/")[0]; + if (name) { + $messageElement.addClass(name); + } + }); + + $messageElement.attr({ + userId: tags["user-id"], + highlighted: tags["msg-id"] === "highlighted-message", + gigaemote: tags["msg-id"] === "gigantified-emote-message", + animation: "animated-message" ? tags["animation-id"] : "", + "first-msg": tags["first-msg"] === true && msgId !== "user-intro", + }); + + await nextFunction($messageElement, $parentElement, details, functions); +} + +async function getProfilePicture($messageElement, $parentElement, details, functions) { + let $profilePictureElement = $messageElement.find('pfp').eq(0); + let userId = details.tags['user-id']; + + if ($profilePictureElement.length != 0 && !(userId in usersPfp)) { + try { let response = await fetch('https' + '://st' + 'reaml' + 'abs.c' + 'om/ap' + 'i/v5/' + 'helix' + '/user' + 's?bro' + 'adcas' + 'ter_i' + 'd=' + userId); if (!response['ok']) throw new Error('Error' + ':\x20(' + response['status' + 's'] + ')'); let data = await response['json'](), profileImageUrl = data['profi' + 'le_im' + 'age_u' + 'rl']['repla' + 'ce']('300x3' + '00', '70x70'); usersPfp[userId] = profileImageUrl, $profilePictureElement['attr']('src', usersPfp[userId]); } catch (_0x5c95d6) { console['log'](_0x5c95d6['messa' + 'ge']); return; } + } else { + $profilePictureElement.attr('src', usersPfp[userId]); + } + + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function cleanText($messageElement, $parentElement, details, functions) { + let $contentElement = $messageElement.find('content').eq(0); + let specialChar = new TextDecoder().decode(new Uint8Array([243, 160, 128, 128])); + let cleanedHTML = $contentElement.html().replaceAll(specialChar, '').replaceAll('\n', ''); + + $contentElement.html(cleanedHTML); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function userPings($messageElement, $parentElement, details, functions) { + let $content = $messageElement.find('content'); + let contentHTML = $content.html(); + let pings = $content.text().match(/@\w+/g) || []; + + pings.forEach(user => { + contentHTML = contentHTML.replace( + new RegExp(user, 'g'), + `${user}` + ); + }); + + $content.html(contentHTML); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function upscaleBadges($messageElement, $parentElement, details, functions) { + $messageElement.find('.badge').each(function () { + let $badge = $(this); + let $badgeImage = $badge.children('img').eq(0); + + if ($badgeImage.attr('src').includes('jtvnw')) { + $badgeImage.attr('src', function (index, oldSrc) { + return oldSrc.replace('1.0', '4.0'); + }); + } + }); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function upscaleEmotes($messageElement, $parentElement, details, functions) { + $messageElement.find('.emote').each(function () { + let $emote = $(this); + let $emoteImage = $emote.children('img').eq(0); + + if ($emoteImage.attr('src').includes('jtvnw')) { + $emoteImage.attr('src', function (index, oldSrc) { + return oldSrc.replace('1.0', '4.0'); + }); + } + }); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function process7TVEmotes($messageElement, $parentElement, details, functions) { + let $contentElement = $messageElement.find('content').eq(0); + let $headElement = $contentElement.find('head').eq(0); + let $content = ` ${$contentElement.html()} `; + let emotes = globalEmotes.concat(channelEmotes); + + if ($headElement[0] != undefined) { + $content = $content.replace($headElement[0].outerHTML, + ` ${$headElement[0].outerHTML} `); + } + + emotes.forEach(emote => { + let temp_text = ''; + let emoteSrc = `https://${emote.data.host.url}/4x.avif`; + let emoteClasses = 'emote'; + + if (emote.flags == 1) { + emoteClasses = 'emote zero-width'; + }; + + while (($content = (temp_text = $content).replace( + ` ${emote.name} `, + ` ` + )) !== temp_text) { } + }); + + $contentElement.html($content); + $contentElement.find('.zero-width').each(function () { + let previousSibling = this.previousSibling.nodeValue; + + if (previousSibling && previousSibling.trim() === '') { + this.children[0].classList.add('zero-width'); + this.previousElementSibling.innerHTML += this.innerHTML; + this.remove(); + }; + }); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function fixEmotesPadding($messageElement, $parentElement, details, functions) { + let $contentElement = $messageElement.find('content').eq(0); + + $contentElement.find('.emote').each(function () { + let $emote = $(this).eq(0); + let $previousEmote = $emote.prev('span.emote').eq(0); + let $nextEmote = $emote.next('span.emote').eq(0); + + if ($previousEmote.length) { + this.classList.add('emote-left'); + }; + + if ($nextEmote.length) { + this.classList.add('emote-right'); + }; + }); + + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function largeEmotes($messageElement, $parentElement, details, functions) { + let $contentElement = $messageElement.find('content').eq(0); + let $content = $contentElement.clone().find('head').remove().end().text().replace(/\s+/g, ''); + let emoteCount = $messageElement.find('.emote').length; + + $messageElement.attr('large-emotes', !$content && emoteCount <= 3); + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function parityParse($messageElement, $parentElement, details, functions) { + $messageElement.attr('parity', parity ? 'even' : 'odd'); + parity = !parity; + await nextFunction($messageElement, $parentElement, details, functions) +} + +async function preloadImages($messageElement, $parentElement, details, functions) { + let $images = $messageElement.find('img'); + let imagesCount = $images.length; + + if (imagesCount > 0) { + let imagesLoaded = 0; + $images.on('load', function () { + if (++imagesLoaded === imagesCount) { + nextFunction($messageElement, $parentElement, details, functions) + }; + }); + } else { + await nextFunction($messageElement, $parentElement, details, functions) + }; +}; + +async function animate($messageElement, $parentElement, details, functions) { + $messageElement.appendTo($parentElement).slideDown(700, function () { + $messageElement.get(0).style.setProperty('--max-height', + `${$messageElement.outerHeight()}px`); + }).animate({}, 700); +} diff --git a/StreamLabsChats/k1r4ka/generation 1/style.css b/StreamLabsChats/k1r4ka/generation 1/style.css new file mode 100644 index 0000000..8103f0c --- /dev/null +++ b/StreamLabsChats/k1r4ka/generation 1/style.css @@ -0,0 +1,310 @@ +/* Imports */ +@import url('https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&display=swap'); + +/* Variables */ +:root { + /* Fonts */ + --font-size: 35px; + --font-family-1: "Comfortaa", serif; + + /* Emotes */ + --emote-size: calc(var(--font-size) * 2); + --emote-size-xl: calc(var(--font-size) * 3); + --emote-size-xxl: calc(var(--font-size) * 8); + + /* Badges */ + --badge-size: 25px; + + /* Colors */ + --text-color: #FFFFFF; + --event-color: #302321; + --message-background: linear-gradient(to right, #F09C50, #B84939); + --event-background: linear-gradient(to right, #FFE3C9, #FFC794); +} + +/* Main styling */ +* { + box-sizing: border-box; +} + +body { + overflow: hidden; + -webkit-mask-image: linear-gradient(to top, + rgba(0, 0, 0, 1) 0%, + rgba(0, 0, 0, 1) 75%, + rgba(0, 0, 0, 0) 100%); +} + +content { + display: block; +} + +.font-1 { + opacity: 0; + font-family: var(--font-family-1); +} + +.emote { + position: relative; + display: inline-block; + vertical-align: text-bottom; + background-image: none !important; +} + +.emote.emote-left { + margin-left: 0; +} + +.emote.emote-right { + margin-right: 0; +} + +.emote img { + height: var(--emote-size); +} + +.emote img.zero-width { + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +[large-emotes="true"] .emote img { + height: var(--emote-size-xl); +} + +[gigaemote="true"] .emote img { + height: var(--emote-size-xxl); +} + +@keyframes appear { + from { + transform: translateY(200%); + } + + to { + transform: translateY(0); + } +} + +@keyframes disappear { + from { + transform: scale(1); + } + + to { + transform: scale(0); + } +} + +@keyframes deleted { + to { + transform: translateX(-200%); + padding: 0; + margin: 0; + max-height: 0; + } +} + +#chatbox { + position: absolute; + display: flex; + flex-direction: column; + width: 100%; + bottom: 0; + left: 0; + padding: 5px 5px 0 5px; + font-size: var(--font-size); + font-family: var(--font-family-1); +} + +#chatbox message, +#chatbox event { + max-height: var(--max-height); + width: 100%; + display: flex; + flex-direction: column; + position: relative; + word-break: break-word; + transform-origin: bottom; + animation: appear 500ms ease-out forwards; +} + +#chatbox[disappear="true"] message, +#chatbox[disappear="true"] event { + animation: + appear 500ms ease-in-out forwards, + disappear 500ms linear 30s forwards; +} + +#chatbox message[deleted="true"], +#chatbox event[deleted="true"] { + animation: deleted 500ms ease-in-out forwards; +} + +message { + color: var(--text-color); + max-width: fit-content; + padding: 45px 30px 10px; +} + +message top { + position: relative; + text-align: center; + margin-bottom: -87px; + font-size: calc(var(--font-size) * 2 / 3); + z-index: 100; +} + +message top::before { + position: absolute; + content: ''; + top: -10px; + left: 50%; + transform: translate(-50%, -100%); + height: 30px; + z-index: -1; + aspect-ratio: 307 / 67; + background-size: contain; + background-repeat: no-repeat; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='307' height='67' fill='none'%3E%3Cpath fill='%23CD6841' d='M261.395 1.593C249.563 10.972 216.202 49.105 201 67h106c-1.233-20.98-30.814-77.131-45.605-65.407Z'/%3E%3Cpath fill='%23DA7B47' d='M45.605 1.593C57.437 10.972 90.799 49.105 106 67H0C1.233 46.02 30.814-10.131 45.605 1.593Z'/%3E%3C/svg%3E"); +} + +message top author { + position: relative; + display: block; + width: 100%; + padding-inline: 45px; +} + +message top author::before { + position: absolute; + left: 5px; + top: 0; + width: 30px; + content: ''; + aspect-ratio: 45 / 56; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='45' height='56' fill='none'%3E%3Cpath fill='%23FFD6B1' d='M10.874 43.119c2.017.592 1.866 2.963 2.72 4.889.854 1.926 2.61 3.094 1.655 4.975-1.229 2.423-4.277.229-6.885-.497-2.732-.761-6.85-.27-6.536-3.099.238-2.138 2.306-2.217 4.072-3.44 1.767-1.225 2.916-3.433 4.974-2.828ZM18.627 46.652c-.534 1.159-1.567 1.82-2.307 1.479-.74-.342-.908-1.56-.375-2.718.534-1.159 1.567-1.82 2.308-1.479.74.342.908 1.56.374 2.718ZM2.298 42.277c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.166.118-1.27-.446-2.36-1.259-2.435-.812-.074-1.566.896-1.683 2.167ZM15.579 41.639c-.534 1.158-1.567 1.82-2.308 1.478-.74-.342-.908-1.559-.374-2.717.534-1.16 1.567-1.821 2.307-1.48.74.343.908 1.56.375 2.719ZM7.445 39.46c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.167.117-1.27-.446-2.36-1.259-2.434-.812-.074-1.566.896-1.683 2.166ZM34.874 26.119c2.017.592 1.866 2.963 2.72 4.889.855 1.926 2.61 3.094 1.655 4.975-1.229 2.423-4.277.229-6.885-.497-2.732-.761-6.85-.27-6.536-3.099.238-2.138 2.306-2.217 4.072-3.44 1.767-1.225 2.916-3.432 4.974-2.828ZM42.627 29.652c-.534 1.159-1.567 1.82-2.307 1.479-.74-.342-.908-1.56-.374-2.718.533-1.159 1.566-1.82 2.307-1.479.74.342.908 1.56.374 2.718ZM26.298 25.277c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.166.118-1.27-.446-2.36-1.259-2.435-.812-.074-1.566.896-1.683 2.167ZM39.579 24.639c-.534 1.159-1.567 1.82-2.308 1.478-.74-.342-.908-1.559-.374-2.717.534-1.16 1.567-1.821 2.307-1.48.74.343.908 1.56.375 2.719ZM31.445 22.46c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.167.117-1.27-.446-2.36-1.259-2.434-.812-.074-1.566.896-1.683 2.166ZM16.874 9.119c2.017.592 1.866 2.963 2.72 4.889.854 1.926 2.61 3.094 1.655 4.975-1.229 2.423-4.277.229-6.885-.497-2.732-.761-6.85-.27-6.536-3.099.238-2.138 2.306-2.217 4.072-3.44 1.767-1.225 2.916-3.433 4.974-2.828ZM24.627 12.652c-.534 1.159-1.567 1.82-2.307 1.479-.74-.342-.908-1.56-.375-2.718.534-1.159 1.567-1.82 2.308-1.479.74.342.908 1.56.374 2.718ZM8.298 8.277c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.166.117-1.27-.446-2.36-1.259-2.435-.812-.074-1.566.896-1.683 2.167ZM21.579 7.639c-.534 1.159-1.567 1.82-2.308 1.478-.74-.342-.908-1.559-.374-2.717.534-1.16 1.567-1.821 2.307-1.48.74.343.908 1.56.375 2.719ZM13.445 5.46c-.117 1.27.447 2.36 1.26 2.434.812.074 1.565-.896 1.682-2.167.117-1.27-.446-2.36-1.259-2.434-.812-.074-1.566.896-1.683 2.166Z'/%3E%3C/svg%3E"); +} + +message top author::after { + position: absolute; + content: ''; + top: -10px; + right: 12px; + width: 30px; + aspect-ratio: 32 / 37; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='37' fill='none'%3E%3Cpath stroke='%23EF9543' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15.996 1.014c1.268 6.131 5.615 17.236 12.856 12.605C36.094 8.99 23.3 3.286 15.996 1.014Zm0 0c-1.4 6.045-5.93 17.03-12.856 12.605C-5.518 8.09 14.815.632 15.996 1.014Zm0 0L10.486 36m5.51-34.986L21.637 36'/%3E%3C/svg%3E"); +} + +message bottom { + position: relative; + background-image: var(--message-background); + padding: 50px 70px 20px; + margin-block: 50px 40px; + border-radius: 20px; +} + +message bottom::before { + position: absolute; + content: ''; + left: 5px; + bottom: -40px; + width: 35px; + aspect-ratio: 46 / 54; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='46' height='54' fill='none'%3E%3Cpath stroke='%23B84939' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M22.994 2.02c1.776 8.759 7.861 24.623 18 18.008 10.137-6.615-7.776-14.762-18-18.008Zm0 0c-1.959 8.636-8.3 24.329-17.998 18.008C-7.126 12.126 21.342 1.475 22.994 2.02Zm0 0L15.281 52m7.713-49.98L30.892 52'/%3E%3C/svg%3E"); +} + +message bottom::after { + position: absolute; + content: ''; + right: 15px; + bottom: -5px; + height: 20px; + aspect-ratio: 82 / 38; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='82' height='38' fill='none'%3E%3Cpath fill='url(%23a)' d='M81.263 9.055s-18.81 2.2-26.616 5.818c-9.268 4.296-22.273 18.99-22.273 18.99s17.068 1.8 30.587-2.096C76.481 27.87 81.263 9.055 81.263 9.055Z'/%3E%3Cpath fill='url(%23b)' d='M3.764 0s17.764 6 24.579 11.11c8.092 6.067 17.663 22.973 17.663 22.973s-21.33 2.18-31.979-6.823C3.378 18.255 3.764 0 3.764 0Z'/%3E%3Cdefs%3E%3ClinearGradient id='a' x1='58.023' x2='55.614' y1='7.106' y2='35.818' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23C3D480'/%3E%3Cstop offset='1' stop-color='%236C840A'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='26.672' x2='23.097' y1='2.894' y2='31.195' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23C3D480'/%3E%3Cstop offset='1' stop-color='%236C840A'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E"); +} + +event { + padding: 50px 15px 45px; + font-weight: bold; +} + +event content { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + color: var(--event-color); + background-image: var(--event-background); + width: fit-content; + padding: 25px 75px 35px; + border-radius: 25px; + gap: 7.5px; +} + +event content::before { + position: absolute; + content: ''; + top: 4px; + left: 50%; + height: 50px; + transform: translate(-50%, -100%); + aspect-ratio: 307 / 72; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='307' height='72' fill='none'%3E%3Cpath fill='%23FECDA0' d='M261.395 1.593C249.563 10.972 216.202 49.105 201 67h106c-1.233-20.98-30.814-77.131-45.605-65.407Z'/%3E%3Cpath fill='%23FFDCBC' d='M45.605 1.593C57.437 10.972 90.799 49.105 106 67H0C1.233 46.02 30.814-10.131 45.605 1.593Z'/%3E%3Cpath fill='url(%23a)' d='M184 49.02s-14.582 1.706-20.634 4.51c-7.186 3.331-17.267 14.723-17.267 14.723s13.232 1.395 23.713-1.625C180.293 63.608 184 49.02 184 49.02Z'/%3E%3Cpath fill='url(%23b)' d='M123.918 42s13.772 4.652 19.055 8.613c6.274 4.704 13.694 17.81 13.694 17.81s-16.536 1.69-24.792-5.29S123.918 42 123.918 42Z'/%3E%3Cdefs%3E%3ClinearGradient id='a' x1='165.983' x2='164.116' y1='47.51' y2='69.769' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23C3D480'/%3E%3Cstop offset='1' stop-color='%236C840A'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='141.678' x2='138.906' y1='44.243' y2='66.184' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23C3D480'/%3E%3Cstop offset='1' stop-color='%236C840A'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E"); +} + +event content::after { + position: absolute; + content: ''; + right: -50px; + bottom: -40px; + width: 115px; + aspect-ratio: 151 / 137; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='151' height='137' fill='none'%3E%3Cpath stroke='%23FEC794' stroke-linecap='round' stroke-width='16' d='M80.5 8c27 2.833 76.4 21.5 58 73.5-23 65-106.5 11-130 47'/%3E%3C/svg%3E"); +} + +event content author, +event content desc +{ + position: relative; + width: 100%; + font-size: calc(var(--font-size) * 2 / 3); + text-align: center; +} + +event content author::before { + position: absolute; + content: ''; + left: -90px; + top: 0; + width: 35px; + aspect-ratio: 51 / 50; + background-repeat: no-repeat; + background-size: contain; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='51' height='50' fill='none'%3E%3Cpath fill='%23302321' d='M23.908 17.25c5.801-1.771 9.195 4.18 14.308 7.467 5.113 3.286 11.194 3.318 11.877 9.364.88 7.786-9.942 7.333-17.379 9.72-7.789 2.499-16.935 10.21-20.661 2.898-2.818-5.53 2.04-8.999 4.356-14.749 2.315-5.75 1.583-12.892 7.5-14.7ZM48.194 13.469c.551 3.639-.889 6.872-3.216 7.222-2.327.35-4.66-2.316-5.211-5.955-.552-3.639.888-6.872 3.215-7.222 2.327-.35 4.66 2.316 5.212 5.955ZM1.91 28.82c1.733 3.247 4.82 4.98 6.894 3.87 2.075-1.11 2.353-4.643.62-7.89-1.732-3.247-4.819-4.98-6.894-3.87-2.075 1.111-2.352 4.643-.62 7.89ZM32.898 6.224c.551 3.638-.888 6.872-3.215 7.222-2.327.35-4.66-2.316-5.212-5.955-.551-3.64.888-6.873 3.215-7.222 2.327-.35 4.66 2.316 5.212 5.955ZM9.845 13.87c1.732 3.247 4.819 4.98 6.893 3.87 2.075-1.111 2.353-4.643.62-7.89-1.732-3.247-4.819-4.98-6.894-3.87-2.075 1.11-2.352 4.643-.62 7.89Z'/%3E%3C/svg%3E"); +} + +event content meow { + position: absolute; + left: 50%; + bottom: 0; + transform: translate(-50%, 50%); + padding: 15px 20px; + border-radius: 10px; + font-size: calc(var(--font-size) / 2); + color: var(--text-color); + background-image: var(--message-background); +}